neue Code Formatierung
This commit is contained in:
parent
be064fb965
commit
0f7627419a
93 changed files with 6864 additions and 6078 deletions
210
BPMN-KI-Test/prompt1.txt
Normal file
210
BPMN-KI-Test/prompt1.txt
Normal 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
11
BPMN-KI-Test/prompt2.txt
Normal 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.
|
||||||
389
BPMN-KI-Test/rechnung-ai-test.bpmn
Normal file
389
BPMN-KI-Test/rechnung-ai-test.bpmn
Normal 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>
|
||||||
207
BPMN-KI-Test/rechnung-ai-test_plain.bpmn
Normal file
207
BPMN-KI-Test/rechnung-ai-test_plain.bpmn
Normal 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
17
BPMN-KI-Test/schema-1.txt
Normal 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
46
BPMN-KI-Test/schema-2.txt
Normal 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
|
||||||
|
|
@ -8,9 +8,15 @@ https://api-console.zoho.eu/
|
||||||
https://api-console.zoho.eu/client/1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
|
https://api-console.zoho.eu/client/1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
|
||||||
|
|
||||||
```
|
```
|
||||||
OrganizationID=20105697367
|
zoho.accesstoken 1000.18f5fbeaf572425b8062d015d541aad5.a704efa994774ef33d7af75106468a13
|
||||||
client ID= 1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
|
zoho.apidomain https://www.zohoapis.eu
|
||||||
client secret= ee9ba49f16e77c64abb89cea13542d2326d8d03ce8
|
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
|
# API Dokumentation
|
||||||
|
|
@ -86,3 +92,16 @@ Danach den Code token kopieren:
|
||||||
1000.7fe6315e8848b92a2f281b885677d37a.428c02dc2309606c86271842f1f67de4
|
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!
|
**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
26
doc/zoho/SECRETS.md
Normal 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/
|
||||||
BIN
doc/zoho/disable-auto-generated-number-01.png
Normal file
BIN
doc/zoho/disable-auto-generated-number-01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
doc/zoho/disable-auto-generated-number-02.png
Normal file
BIN
doc/zoho/disable-auto-generated-number-02.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
File diff suppressed because it is too large
Load diff
|
|
@ -23,9 +23,8 @@ import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der AGLAnalyticControllerOPListe berechnet Analyse Daten über alle offenen
|
* Der AGLAnalyticControllerOPListe berechnet Analyse Daten über alle offenen
|
||||||
* Rechnungen
|
* Rechnungen und bietet im Workflow noch eine Excel-Export Funktion
|
||||||
* und bietet im Workflow noch eine Excel-Export Funktion
|
*
|
||||||
*
|
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -33,176 +32,173 @@ import jakarta.inject.Named;
|
||||||
@ConversationScoped
|
@ConversationScoped
|
||||||
public class AGLAnalyticControllerOPListe implements Serializable {
|
public class AGLAnalyticControllerOPListe implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
|
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected DocumentService documentService;
|
protected DocumentService documentService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected AGLConfigController aglConfigController;
|
protected AGLConfigController aglConfigController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected WorkflowController workflowController;
|
protected WorkflowController workflowController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
TeamService teamService;
|
TeamService teamService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ResourceBundleHandler resourceBundleHandler;
|
ResourceBundleHandler resourceBundleHandler;
|
||||||
|
|
||||||
TreeMap<String, DebitorStatistikData> stats = null;
|
TreeMap<String, DebitorStatistikData> stats = null;
|
||||||
|
|
||||||
String departmentID;
|
String departmentID;
|
||||||
String departmentIDLast = null;
|
String departmentIDLast = null;
|
||||||
// String departmentName;
|
// String departmentName;
|
||||||
ItemCollection department;
|
ItemCollection department;
|
||||||
|
|
||||||
int countAll = 0;
|
int countAll = 0;
|
||||||
int countOpen = 0;
|
int countOpen = 0;
|
||||||
int countDue = 0;
|
int countDue = 0;
|
||||||
int countDunning = 0;
|
int countDunning = 0;
|
||||||
boolean refreshCalculation = false;
|
boolean refreshCalculation = false;
|
||||||
|
|
||||||
public void onEvent(@Observes AnalyticEvent event) {
|
public void onEvent(@Observes AnalyticEvent event) {
|
||||||
|
|
||||||
if (!event.getWorkitem().getModelVersion().contains("analyse-opliste-")) {
|
if (!event.getWorkitem().getModelVersion().contains("analyse-opliste-")) {
|
||||||
// no op
|
// no op
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
department = null;
|
department = null;
|
||||||
departmentID = event.getWorkitem().getItemValueString("space.ref");
|
departmentID = event.getWorkitem().getItemValueString("space.ref");
|
||||||
if (departmentIDLast == null || !departmentID.equals(departmentIDLast)) {
|
if (departmentIDLast == null || !departmentID.equals(departmentIDLast)) {
|
||||||
department = documentService.load(departmentID);
|
department = documentService.load(departmentID);
|
||||||
if (department != null) {
|
if (department != null) {
|
||||||
event.getWorkitem().setItemValue("space.name", department.getItemValueString("name"));
|
event.getWorkitem().setItemValue("space.name", department.getItemValueString("name"));
|
||||||
}
|
}
|
||||||
departmentIDLast = departmentID;
|
departmentIDLast = departmentID;
|
||||||
resetStats(event);
|
resetStats(event);
|
||||||
calculateStats();
|
calculateStats();
|
||||||
refreshCalculation = true;
|
refreshCalculation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use cache?
|
// use cache?
|
||||||
if (event.getWorkitem().hasItem(event.getKey())) {
|
if (event.getWorkitem().hasItem(event.getKey())) {
|
||||||
// logger.info(" use cache for " + event.getKey());
|
// logger.info(" use cache for " + event.getKey());
|
||||||
// no op
|
// no op
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String link = "/pages/workitems/worklist.xhtml";
|
String link = "/pages/workitems/worklist.xhtml";
|
||||||
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
|
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
|
||||||
ItemCollection process = documentService
|
ItemCollection process = documentService
|
||||||
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
||||||
if (process != null) {
|
if (process != null) {
|
||||||
link = link + "?processref=" + process.getUniqueID() // + "&modelversion=rechnungsausgang*"
|
link = link + "?processref=" + process.getUniqueID() // + "&modelversion=rechnungsausgang*"
|
||||||
+ "&spaceref=" + departmentID;
|
+ "&spaceref=" + departmentID;
|
||||||
}
|
}
|
||||||
if ("analytic.invoices.count.all".equals(event.getKey())) {
|
if ("analytic.invoices.count.all".equals(event.getKey())) {
|
||||||
event.setValue("" + countAll);
|
event.setValue("" + countAll);
|
||||||
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
||||||
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.all"));
|
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.all"));
|
||||||
event.getWorkitem().setItemValue("invoices.total", event.getValue());
|
event.getWorkitem().setItemValue("invoices.total", event.getValue());
|
||||||
event.setLink(link);
|
event.setLink(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("analytic.invoices.count.open".equals(event.getKey())) {
|
if ("analytic.invoices.count.open".equals(event.getKey())) {
|
||||||
event.setValue("" + (countOpen));
|
event.setValue("" + (countOpen));
|
||||||
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
||||||
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.open"));
|
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.open"));
|
||||||
event.getWorkitem().setItemValue("invoices.total.open", event.getValue());
|
event.getWorkitem().setItemValue("invoices.total.open", event.getValue());
|
||||||
event.setLink(link);
|
event.setLink(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("analytic.invoices.count.due".equals(event.getKey())) {
|
if ("analytic.invoices.count.due".equals(event.getKey())) {
|
||||||
event.setValue("" + countDue);
|
event.setValue("" + countDue);
|
||||||
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
||||||
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.due"));
|
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.due"));
|
||||||
event.getWorkitem().setItemValue("invoices.total.due", event.getValue());
|
event.getWorkitem().setItemValue("invoices.total.due", event.getValue());
|
||||||
event.setLink(link);
|
event.setLink(link);
|
||||||
}
|
}
|
||||||
if ("analytic.invoices.count.dunning".equals(event.getKey())) {
|
if ("analytic.invoices.count.dunning".equals(event.getKey())) {
|
||||||
event.setValue("" + countDunning);
|
event.setValue("" + countDunning);
|
||||||
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
|
||||||
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.dunning"));
|
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.dunning"));
|
||||||
event.getWorkitem().setItemValue("invoices.total.dunning", event.getValue());
|
event.getWorkitem().setItemValue("invoices.total.dunning", event.getValue());
|
||||||
event.setLink(link);
|
event.setLink(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset cached analytic keys
|
* Reset cached analytic keys
|
||||||
*/
|
*/
|
||||||
private void resetStats(AnalyticEvent event) {
|
private void resetStats(AnalyticEvent event) {
|
||||||
event.getWorkitem().removeItem("analytic.invoices.count.all");
|
event.getWorkitem().removeItem("analytic.invoices.count.all");
|
||||||
event.getWorkitem().removeItem("analytic.invoices.count.open");
|
event.getWorkitem().removeItem("analytic.invoices.count.open");
|
||||||
event.getWorkitem().removeItem("analytic.invoices.count.due");
|
event.getWorkitem().removeItem("analytic.invoices.count.due");
|
||||||
event.getWorkitem().removeItem("analytic.invoices.count.dunning");
|
event.getWorkitem().removeItem("analytic.invoices.count.dunning");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Läd die statistik daten zu einem department die Anzahl an aktuellen
|
* Läd die statistik daten zu einem department die Anzahl an aktuellen
|
||||||
* Rechnungen zu ermitteln
|
* Rechnungen zu ermitteln
|
||||||
*
|
*
|
||||||
* int countAll = 0;
|
* int countAll = 0; int countOpen = 0; int countDue = 0; int countDunning = 0;
|
||||||
* int countOpen = 0;
|
*
|
||||||
* int countDue = 0;
|
*/
|
||||||
* int countDunning = 0;
|
private void calculateStats() {
|
||||||
*
|
long l = System.currentTimeMillis();
|
||||||
*/
|
|
||||||
private void calculateStats() {
|
|
||||||
long l = System.currentTimeMillis();
|
|
||||||
|
|
||||||
countAll = 0;
|
countAll = 0;
|
||||||
countDue = 0;
|
countDue = 0;
|
||||||
countDunning = 0;
|
countDunning = 0;
|
||||||
logger.info(" ├──calculate stats for " + departmentID + "....");
|
logger.info(" ├──calculate stats for " + departmentID + "....");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (departmentID == null || !departmentID.isEmpty()) {
|
if (departmentID == null || !departmentID.isEmpty()) {
|
||||||
countAll = documentService.count("(type:workitem) AND $uniqueidref:" + departmentID
|
countAll = documentService.count(
|
||||||
+ " AND $modelversion:rechnungsausgang-*");
|
"(type:workitem) AND $uniqueidref:" + departmentID + " AND $modelversion:rechnungsausgang-*");
|
||||||
|
|
||||||
countDue = documentService.count("(type:workitem) AND $uniqueidref:" + departmentID
|
countDue = documentService.count("(type:workitem) AND $uniqueidref:" + departmentID
|
||||||
+ " AND $modelversion:rechnungsausgang-* AND $taskid:[5100 TO 5199]");
|
+ " AND $modelversion:rechnungsausgang-* AND $taskid:[5100 TO 5199]");
|
||||||
countDunning = documentService.count("(type:workitem) AND $uniqueidref:" + departmentID
|
countDunning = documentService.count("(type:workitem) AND $uniqueidref:" + departmentID
|
||||||
+ " AND $modelversion:rechnungsausgang-* AND $taskid:[5200 TO 5399]");
|
+ " AND $modelversion:rechnungsausgang-* AND $taskid:[5200 TO 5399]");
|
||||||
|
|
||||||
countOpen = countAll - countDue - countDunning;
|
countOpen = countAll - countDue - countDunning;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// countAll=documentService.count("(type:workitem OR type:workitemarchive) AND
|
// countAll=documentService.count("(type:workitem OR type:workitemarchive) AND
|
||||||
// $modelversion:rechnungsausgang-*")
|
// $modelversion:rechnungsausgang-*")
|
||||||
|
|
||||||
countAll = documentService.count("(type:workitem) AND $modelversion:rechnungsausgang-*");
|
countAll = documentService.count("(type:workitem) AND $modelversion:rechnungsausgang-*");
|
||||||
|
|
||||||
countDue = documentService
|
countDue = documentService
|
||||||
.count("(type:workitem) AND $modelversion:rechnungsausgang-* AND $taskid:[5100 TO 5199]");
|
.count("(type:workitem) AND $modelversion:rechnungsausgang-* AND $taskid:[5100 TO 5199]");
|
||||||
|
|
||||||
countDunning = documentService
|
countDunning = documentService
|
||||||
.count("(type:workitem) AND $modelversion:rechnungsausgang-* AND $taskid:[5200 TO 5399]");
|
.count("(type:workitem) AND $modelversion:rechnungsausgang-* AND $taskid:[5200 TO 5399]");
|
||||||
countOpen = countAll - countDue - countDunning;
|
countOpen = countAll - countDue - countDunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
logger.warning("Failed to query invoices: " + e.getMessage());
|
logger.warning("Failed to query invoices: " + e.getMessage());
|
||||||
|
|
||||||
}
|
}
|
||||||
logger.info(" ├──calculate stats took " + (System.currentTimeMillis() - l) + "ms");
|
logger.info(" ├──calculate stats took " + (System.currentTimeMillis() - l) + "ms");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatCurrency(Double value) {
|
private String formatCurrency(Double value) {
|
||||||
|
|
||||||
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.getDefault());
|
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.getDefault());
|
||||||
symbols.setGroupingSeparator('.');
|
symbols.setGroupingSeparator('.');
|
||||||
symbols.setDecimalSeparator(',');
|
symbols.setDecimalSeparator(',');
|
||||||
DecimalFormat formatter = new DecimalFormat("#,##0.00", symbols);
|
DecimalFormat formatter = new DecimalFormat("#,##0.00", symbols);
|
||||||
|
|
||||||
return formatter.format(value);
|
return formatter.format(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import jakarta.json.JsonObjectBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der AGLAnalyticController berechnet verschiedene Analyse Daten
|
* Der AGLAnalyticController berechnet verschiedene Analyse Daten
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -36,497 +36,477 @@ import jakarta.json.JsonObjectBuilder;
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class AGLAnalyticControllerSteuer implements Serializable {
|
public class AGLAnalyticControllerSteuer implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
|
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected DocumentService documentService;
|
protected DocumentService documentService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
TeamService teamService;
|
TeamService teamService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected WorkflowController workflowController;
|
protected WorkflowController workflowController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
||||||
protected DebitorStatistikController debitorStatistikController;
|
protected DebitorStatistikController debitorStatistikController;
|
||||||
|
|
||||||
List<ItemCollection> steuerbescheide = null;
|
List<ItemCollection> steuerbescheide = null;
|
||||||
|
|
||||||
public void onEvent(@Observes AnalyticEvent event) {
|
public void onEvent(@Observes AnalyticEvent event) {
|
||||||
|
|
||||||
if (!"workitem".equals(event.getWorkitem().getType())
|
if (!"workitem".equals(event.getWorkitem().getType())
|
||||||
|| !event.getWorkitem().getModelVersion().startsWith("analyse-steuer")) {
|
|| !event.getWorkitem().getModelVersion().startsWith("analyse-steuer")) {
|
||||||
// no op
|
// no op
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemCollection process = documentService
|
ItemCollection process = documentService
|
||||||
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
||||||
String link = "/pages/workitems/worklist.xhtml";
|
String link = "/pages/workitems/worklist.xhtml";
|
||||||
if (process != null) {
|
if (process != null) {
|
||||||
link = link + "?processref=" + process.getUniqueID()
|
link = link + "?processref=" + process.getUniqueID() + "&workflowgroup=Steuerbescheid";
|
||||||
+ "&workflowgroup=Steuerbescheid";
|
}
|
||||||
}
|
if ("analytic.steuer.eust".equals(event.getKey())) {
|
||||||
if ("analytic.steuer.eust".equals(event.getKey())) {
|
event.setValue(computeSteuerbescheideEUST());
|
||||||
event.setValue(computeSteuerbescheideEUST());
|
event.setLabel("EUR");
|
||||||
event.setLabel("EUR");
|
event.setDescription("Gesamt Einfuhrumsatzsteuer (EUSt)");
|
||||||
event.setDescription("Gesamt Einfuhrumsatzsteuer (EUSt)");
|
event.getWorkitem().setItemValue("eust.total", event.getValue());
|
||||||
event.getWorkitem().setItemValue("eust.total", event.getValue());
|
event.setLink(link);
|
||||||
event.setLink(link);
|
}
|
||||||
}
|
if ("analytic.steuer.zoll".equals(event.getKey())) {
|
||||||
if ("analytic.steuer.zoll".equals(event.getKey())) {
|
event.setValue(computeSteuerbescheideZoll());
|
||||||
event.setValue(computeSteuerbescheideZoll());
|
event.setLabel("EUR");
|
||||||
event.setLabel("EUR");
|
event.setDescription("Gesamt Zölle (ZOLLEU)");
|
||||||
event.setDescription("Gesamt Zölle (ZOLLEU)");
|
event.setLink(link);
|
||||||
event.setLink(link);
|
}
|
||||||
}
|
|
||||||
|
if ("analytic.steuer.total".equals(event.getKey())) {
|
||||||
if ("analytic.steuer.total".equals(event.getKey())) {
|
event.setValue(computeSteuerbescheideTotal());
|
||||||
event.setValue(computeSteuerbescheideTotal());
|
event.setLabel("EUR");
|
||||||
event.setLabel("EUR");
|
event.setDescription("Alle Steuerbescheide die noch nicht abgerechnet wurden.");
|
||||||
event.setDescription("Alle Steuerbescheide die noch nicht abgerechnet wurden.");
|
event.setLink(link);
|
||||||
event.setLink(link);
|
}
|
||||||
}
|
|
||||||
|
if ("analytic.steuer.saldo".equals(event.getKey())) {
|
||||||
if ("analytic.steuer.saldo".equals(event.getKey())) {
|
event.setValue(computeSteuerbescheideSaldo());
|
||||||
event.setValue(computeSteuerbescheideSaldo());
|
event.setLabel("EUR");
|
||||||
event.setLabel("EUR");
|
event.setDescription("Saldo aller Steuerbescheide die noch nicht abgerechnet wurden.");
|
||||||
event.setDescription("Saldo aller Steuerbescheide die noch nicht abgerechnet wurden.");
|
event.setLink(link);
|
||||||
event.setLink(link);
|
}
|
||||||
}
|
|
||||||
|
if ("analytic.steuer.due".equals(event.getKey())) {
|
||||||
if ("analytic.steuer.due".equals(event.getKey())) {
|
event.setValue(computeSteuerbescheideSaldoDue());
|
||||||
event.setValue(computeSteuerbescheideSaldoDue());
|
event.setLabel("EUR");
|
||||||
event.setLabel("EUR");
|
event.setDescription("Saldo aller überfälligen Steuerbescheide die noch nicht abgerechnet wurden.");
|
||||||
event.setDescription("Saldo aller überfälligen Steuerbescheide die noch nicht abgerechnet wurden.");
|
// event.setLink(link + "&task=Überfällig");
|
||||||
// event.setLink(link + "&task=Überfällig");
|
event.setLink(link + "&task=1200");
|
||||||
event.setLink(link + "&task=1200");
|
}
|
||||||
}
|
|
||||||
|
// Charts
|
||||||
// Charts
|
|
||||||
|
if ("analytic.steuer.trend".equals(event.getKey())) {
|
||||||
if ("analytic.steuer.trend".equals(event.getKey())) {
|
event.setValue(accumulateSteuerbescheideByWeek());
|
||||||
event.setValue(accumulateSteuerbescheideByWeek());
|
event.setLabel("Zoll & EUST");
|
||||||
event.setLabel("Zoll & EUST");
|
event.setDescription("Fälligkeiten nach KW");
|
||||||
event.setDescription("Fälligkeiten nach KW");
|
}
|
||||||
}
|
|
||||||
|
if ("analytic.steuer.trend.abteilung".equals(event.getKey())) {
|
||||||
if ("analytic.steuer.trend.abteilung".equals(event.getKey())) {
|
event.setValue(accumulateSteuerbescheideAbteilungByWeek());
|
||||||
event.setValue(accumulateSteuerbescheideAbteilungByWeek());
|
event.setLabel("Nach Abteilungen");
|
||||||
event.setLabel("Nach Abteilungen");
|
event.setDescription("Offene Salden nach KW pro Abteilung");
|
||||||
event.setDescription("Offene Salden nach KW pro Abteilung");
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* Berechnet die Summe aller offenen EUST Beträge // tax.code=[0],
|
||||||
* Berechnet die Summe aller offenen EUST Beträge
|
* amount=[3885.16], activity.type=[EUST], // filenumber=[LA-PAP-2408-024]}
|
||||||
* // tax.code=[0], amount=[3885.16], activity.type=[EUST],
|
*
|
||||||
* // filenumber=[LA-PAP-2408-024]}
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
private double computeSteuerbescheideEUST() {
|
||||||
*/
|
logger.fine("compute EUST...");
|
||||||
private double computeSteuerbescheideEUST() {
|
List<ItemCollection> list = getSteuerbescheide();
|
||||||
logger.fine("compute EUST...");
|
double result = 0;
|
||||||
List<ItemCollection> list = getSteuerbescheide();
|
|
||||||
double result = 0;
|
for (ItemCollection steuerItemCol : list) {
|
||||||
|
result = result + getZollBySteuerBeleg(steuerItemCol, "EUST");
|
||||||
for (ItemCollection steuerItemCol : list) {
|
|
||||||
result = result + getZollBySteuerBeleg(steuerItemCol, "EUST");
|
}
|
||||||
|
return InvoiceUtil.round(result);
|
||||||
}
|
}
|
||||||
return InvoiceUtil.round(result);
|
|
||||||
}
|
/**
|
||||||
|
* Berechnet die Summe aller offenen Zoll Beträge
|
||||||
/**
|
*
|
||||||
* Berechnet die Summe aller offenen Zoll Beträge
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
private double computeSteuerbescheideZoll() {
|
||||||
*/
|
logger.fine("compute Zoll...");
|
||||||
private double computeSteuerbescheideZoll() {
|
List<ItemCollection> list = getSteuerbescheide();
|
||||||
logger.fine("compute Zoll...");
|
double result = 0;
|
||||||
List<ItemCollection> list = getSteuerbescheide();
|
for (ItemCollection steuerItemCol : list) {
|
||||||
double result = 0;
|
result = result + getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
||||||
for (ItemCollection steuerItemCol : list) {
|
}
|
||||||
result = result + getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
return InvoiceUtil.round(result);
|
||||||
}
|
}
|
||||||
return InvoiceUtil.round(result);
|
|
||||||
}
|
/**
|
||||||
|
* Berechnet die Summe aller überfälligen steuer Beträge $taskID=1200
|
||||||
/**
|
*
|
||||||
* Berechnet die Summe aller überfälligen steuer Beträge $taskID=1200
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
private double computeSteuerbescheideSaldo() {
|
||||||
*/
|
logger.fine("compute saldo...");
|
||||||
private double computeSteuerbescheideSaldo() {
|
List<ItemCollection> list = getSteuerbescheide();
|
||||||
logger.fine("compute saldo...");
|
double result = 0;
|
||||||
List<ItemCollection> list = getSteuerbescheide();
|
for (ItemCollection steuerItemCol : list) {
|
||||||
double result = 0;
|
result = result + steuerItemCol.getItemValueDouble("invoice.saldo");
|
||||||
for (ItemCollection steuerItemCol : list) {
|
}
|
||||||
result = result + steuerItemCol.getItemValueDouble("invoice.saldo");
|
return InvoiceUtil.round(result);
|
||||||
}
|
|
||||||
return InvoiceUtil.round(result);
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Berechnet die Summe aller überfälligen steuer Beträge $taskID=1200
|
||||||
/**
|
*
|
||||||
* Berechnet die Summe aller überfälligen steuer Beträge $taskID=1200
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
private double computeSteuerbescheideTotal() {
|
||||||
*/
|
logger.fine("compute total...");
|
||||||
private double computeSteuerbescheideTotal() {
|
List<ItemCollection> list = getSteuerbescheide();
|
||||||
logger.fine("compute total...");
|
double result = 0;
|
||||||
List<ItemCollection> list = getSteuerbescheide();
|
for (ItemCollection steuerItemCol : list) {
|
||||||
double result = 0;
|
result = result + steuerItemCol.getItemValueDouble("invoice.total.net");
|
||||||
for (ItemCollection steuerItemCol : list) {
|
}
|
||||||
result = result + steuerItemCol.getItemValueDouble("invoice.total.net");
|
return InvoiceUtil.round(result);
|
||||||
}
|
}
|
||||||
return InvoiceUtil.round(result);
|
|
||||||
}
|
/**
|
||||||
|
* Berechnet die Summe aller überfälligen steuer Beträge $taskID=1200
|
||||||
/**
|
*
|
||||||
* Berechnet die Summe aller überfälligen steuer Beträge $taskID=1200
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
private double computeSteuerbescheideSaldoDue() {
|
||||||
*/
|
logger.fine("compute EUST...");
|
||||||
private double computeSteuerbescheideSaldoDue() {
|
List<ItemCollection> list = getSteuerbescheide();
|
||||||
logger.fine("compute EUST...");
|
double result = 0;
|
||||||
List<ItemCollection> list = getSteuerbescheide();
|
for (ItemCollection steuerItemCol : list) {
|
||||||
double result = 0;
|
if (steuerItemCol.getTaskID() == 1200) {
|
||||||
for (ItemCollection steuerItemCol : list) {
|
result = result + steuerItemCol.getItemValueDouble("invoice.saldo");
|
||||||
if (steuerItemCol.getTaskID() == 1200) {
|
}
|
||||||
result = result + steuerItemCol.getItemValueDouble("invoice.saldo");
|
}
|
||||||
}
|
return InvoiceUtil.round(result);
|
||||||
}
|
|
||||||
return InvoiceUtil.round(result);
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Berechnet die summ zoll/eust für einen Beleg
|
||||||
/**
|
*
|
||||||
* Berechnet die summ zoll/eust für einen Beleg
|
* @param steuerItemCol
|
||||||
*
|
* @return
|
||||||
* @param steuerItemCol
|
*/
|
||||||
* @return
|
private double getZollBySteuerBeleg(ItemCollection steuerItemCol, String type) {
|
||||||
*/
|
double result = 0;
|
||||||
private double getZollBySteuerBeleg(ItemCollection steuerItemCol, String type) {
|
List<ItemCollection> positionsTabelle = InvoiceUtil.explodeChildList(steuerItemCol);
|
||||||
double result = 0;
|
for (ItemCollection pos : positionsTabelle) {
|
||||||
List<ItemCollection> positionsTabelle = InvoiceUtil.explodeChildList(steuerItemCol);
|
if (type.equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
||||||
for (ItemCollection pos : positionsTabelle) {
|
result = result + pos.getItemValueDouble("amount");
|
||||||
if (type.equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
}
|
||||||
result = result + pos.getItemValueDouble("amount");
|
}
|
||||||
}
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
private List<ItemCollection> getSteuerbescheide() {
|
||||||
|
if (steuerbescheide != null) {
|
||||||
private List<ItemCollection> getSteuerbescheide() {
|
return steuerbescheide;
|
||||||
if (steuerbescheide != null) {
|
}
|
||||||
return steuerbescheide;
|
// compute steuerbescheide....
|
||||||
}
|
logger.info("Load Steuerbescheide for analytics....");
|
||||||
// compute steuerbescheide....
|
String query = "(type:workitem ) AND ($workflowgroup:\"Steuerbescheid\")";
|
||||||
logger.info("Load Steuerbescheide for analytics....");
|
try {
|
||||||
String query = "(type:workitem ) AND ($workflowgroup:\"Steuerbescheid\")";
|
steuerbescheide = documentService.find(query, 999, 0, "$created", false);
|
||||||
try {
|
return steuerbescheide;
|
||||||
steuerbescheide = documentService.find(query, 999, 0, "$created", false);
|
} catch (QueryException e) {
|
||||||
return steuerbescheide;
|
logger.severe("Failed to get invoices: " + e.getMessage());
|
||||||
} catch (QueryException e) {
|
}
|
||||||
logger.severe("Failed to get invoices: " + e.getMessage());
|
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
return null;
|
|
||||||
}
|
/**
|
||||||
|
* Berechnet Chart daten aller Steuerbescheide bei KW
|
||||||
/**
|
*
|
||||||
* Berechnet Chart daten aller Steuerbescheide bei KW
|
* <pre>
|
||||||
*
|
*
|
||||||
* <pre>
|
chartCfg = {
|
||||||
*
|
type: 'bar',
|
||||||
chartCfg = {
|
data: {
|
||||||
type: 'bar',
|
datasets: [{
|
||||||
data: {
|
data: [20, 10],
|
||||||
datasets: [{
|
}],
|
||||||
data: [20, 10],
|
labels: ['1', '2']
|
||||||
}],
|
}
|
||||||
labels: ['1', '2']
|
}
|
||||||
}
|
*
|
||||||
}
|
* </pre>
|
||||||
*
|
*
|
||||||
* </pre>
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
private String accumulateSteuerbescheideByWeek() {
|
||||||
*/
|
logger.fine("accumulate steuer by week...");
|
||||||
private String accumulateSteuerbescheideByWeek() {
|
|
||||||
logger.fine("accumulate steuer by week...");
|
List<ItemCollection> list = getSteuerbescheide();
|
||||||
|
Map<Integer, SteuerData> saldoByWeek = new HashMap<>();
|
||||||
List<ItemCollection> list = getSteuerbescheide();
|
Calendar calendar = Calendar.getInstance();
|
||||||
Map<Integer, SteuerData> saldoByWeek = new HashMap<>();
|
int earliestWeek = Integer.MAX_VALUE;
|
||||||
Calendar calendar = Calendar.getInstance();
|
int latestWeek = Integer.MIN_VALUE;
|
||||||
int earliestWeek = Integer.MAX_VALUE;
|
|
||||||
int latestWeek = Integer.MIN_VALUE;
|
// Step 1: Group saldo by week
|
||||||
|
for (ItemCollection steuerItemCol : list) {
|
||||||
// Step 1: Group saldo by week
|
double saldo = steuerItemCol.getItemValueDouble("invoice.saldo");
|
||||||
for (ItemCollection steuerItemCol : list) {
|
double total = steuerItemCol.getItemValueDouble("invoice.total.net");
|
||||||
double saldo = steuerItemCol.getItemValueDouble("invoice.saldo");
|
Date date = steuerItemCol.getItemValueDate("invoice.date");
|
||||||
double total = steuerItemCol.getItemValueDouble("invoice.total.net");
|
|
||||||
Date date = steuerItemCol.getItemValueDate("invoice.date");
|
// Get the week number and year from the date
|
||||||
|
calendar.setTime(date);
|
||||||
// Get the week number and year from the date
|
int weekNumber = calendar.get(Calendar.WEEK_OF_YEAR);
|
||||||
calendar.setTime(date);
|
int year = calendar.get(Calendar.YEAR);
|
||||||
int weekNumber = calendar.get(Calendar.WEEK_OF_YEAR);
|
int yearWeek = year * 100 + weekNumber; // Unique key for each year + week combination
|
||||||
int year = calendar.get(Calendar.YEAR);
|
|
||||||
int yearWeek = year * 100 + weekNumber; // Unique key for each year + week combination
|
// Accumulate the saldo per week
|
||||||
|
SteuerData steuerDataByWeek = saldoByWeek.getOrDefault(yearWeek, new SteuerData());
|
||||||
// Accumulate the saldo per week
|
double eust = getZollBySteuerBeleg(steuerItemCol, "EUST");
|
||||||
SteuerData steuerDataByWeek = saldoByWeek.getOrDefault(yearWeek, new SteuerData());
|
double zoll = getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
||||||
double eust = getZollBySteuerBeleg(steuerItemCol, "EUST");
|
steuerDataByWeek.add(eust, zoll, total, saldo, "");
|
||||||
double zoll = getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
|
||||||
steuerDataByWeek.add(eust, zoll, total, saldo, "");
|
saldoByWeek.put(yearWeek, steuerDataByWeek);
|
||||||
|
|
||||||
saldoByWeek.put(yearWeek, steuerDataByWeek);
|
// Track the earliest and latest weeks
|
||||||
|
earliestWeek = Math.min(earliestWeek, yearWeek);
|
||||||
// Track the earliest and latest weeks
|
latestWeek = Math.max(latestWeek, yearWeek);
|
||||||
earliestWeek = Math.min(earliestWeek, yearWeek);
|
}
|
||||||
latestWeek = Math.max(latestWeek, yearWeek);
|
|
||||||
}
|
// Step 2: Prepare the JSON structure and ensure we have all weeks from earliest
|
||||||
|
// to latest
|
||||||
// Step 2: Prepare the JSON structure and ensure we have all weeks from earliest
|
JsonArrayBuilder dataBuilderSaldo = Json.createArrayBuilder();
|
||||||
// to latest
|
JsonArrayBuilder dataBuilderEust = Json.createArrayBuilder();
|
||||||
JsonArrayBuilder dataBuilderSaldo = Json.createArrayBuilder();
|
JsonArrayBuilder dataBuilderZoll = Json.createArrayBuilder();
|
||||||
JsonArrayBuilder dataBuilderEust = Json.createArrayBuilder();
|
JsonArrayBuilder labelsBuilder = Json.createArrayBuilder();
|
||||||
JsonArrayBuilder dataBuilderZoll = Json.createArrayBuilder();
|
|
||||||
JsonArrayBuilder labelsBuilder = Json.createArrayBuilder();
|
Calendar startCal = Calendar.getInstance();
|
||||||
|
startCal.set(Calendar.YEAR, earliestWeek / 100);
|
||||||
Calendar startCal = Calendar.getInstance();
|
startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
|
||||||
startCal.set(Calendar.YEAR, earliestWeek / 100);
|
|
||||||
startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
|
Calendar endCal = Calendar.getInstance();
|
||||||
|
endCal.set(Calendar.YEAR, latestWeek / 100);
|
||||||
Calendar endCal = Calendar.getInstance();
|
endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
|
||||||
endCal.set(Calendar.YEAR, latestWeek / 100);
|
|
||||||
endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
|
while (!startCal.after(endCal)) {
|
||||||
|
int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
|
||||||
while (!startCal.after(endCal)) {
|
int year = startCal.get(Calendar.YEAR);
|
||||||
int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
|
int yearWeek = year * 100 + weekNumber;
|
||||||
int year = startCal.get(Calendar.YEAR);
|
|
||||||
int yearWeek = year * 100 + weekNumber;
|
// Add the saldo for the week or 0.0 if no data
|
||||||
|
SteuerData steuerData = saldoByWeek.getOrDefault(yearWeek, new SteuerData());
|
||||||
// Add the saldo for the week or 0.0 if no data
|
dataBuilderSaldo.add(steuerData.saldo);
|
||||||
SteuerData steuerData = saldoByWeek.getOrDefault(yearWeek, new SteuerData());
|
dataBuilderEust.add(steuerData.eust);
|
||||||
dataBuilderSaldo.add(steuerData.saldo);
|
dataBuilderZoll.add(steuerData.zoll);
|
||||||
dataBuilderEust.add(steuerData.eust);
|
labelsBuilder.add(weekNumber + "/" + year); // Label as 'week/year'
|
||||||
dataBuilderZoll.add(steuerData.zoll);
|
|
||||||
labelsBuilder.add(weekNumber + "/" + year); // Label as 'week/year'
|
// Move to the next week
|
||||||
|
startCal.add(Calendar.WEEK_OF_YEAR, 1);
|
||||||
// Move to the next week
|
}
|
||||||
startCal.add(Calendar.WEEK_OF_YEAR, 1);
|
|
||||||
}
|
// Step 3: Prepare the JSON structure
|
||||||
|
JsonObjectBuilder jsonBuilder = Json
|
||||||
// Step 3: Prepare the JSON structure
|
.createObjectBuilder().add("type", "bar").add("data", Json
|
||||||
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder()
|
.createObjectBuilder().add("datasets", Json.createArrayBuilder()
|
||||||
.add("type", "bar")
|
|
||||||
.add("data", Json.createObjectBuilder()
|
.add(Json.createObjectBuilder() // First dataset for 'tax'
|
||||||
.add("datasets", Json.createArrayBuilder()
|
.add("label", "Zoll").add("backgroundColor", "#96f").add("borderWidth", 1)
|
||||||
|
.add("data", dataBuilderZoll))
|
||||||
.add(Json.createObjectBuilder() // First dataset for 'tax'
|
.add(Json.createObjectBuilder() // Second dataset for 'eust'
|
||||||
.add("label", "Zoll")
|
.add("label", "EUSt").add("backgroundColor", "#36a2eb").add("borderWidth", 1)
|
||||||
.add("backgroundColor", "#96f")
|
.add("data", dataBuilderEust))
|
||||||
.add("borderWidth", 1)
|
.add(Json.createObjectBuilder() // Third dataset for 'Saldo'
|
||||||
.add("data", dataBuilderZoll))
|
.add("label", "Saldo").add("backgroundColor", "#ff6384").add("borderWidth", 1)
|
||||||
.add(Json.createObjectBuilder() // Second dataset for 'eust'
|
.add("data", dataBuilderSaldo)))
|
||||||
.add("label", "EUSt")
|
|
||||||
.add("backgroundColor", "#36a2eb")
|
.add("labels", labelsBuilder));
|
||||||
.add("borderWidth", 1)
|
|
||||||
.add("data", dataBuilderEust))
|
// Step 4: Return the JSON structure as a string
|
||||||
.add(Json.createObjectBuilder() // Third dataset for 'Saldo'
|
JsonObject chartCfg = jsonBuilder.build();
|
||||||
.add("label", "Saldo")
|
return chartCfg.toString();
|
||||||
.add("backgroundColor", "#ff6384")
|
}
|
||||||
.add("borderWidth", 1)
|
|
||||||
.add("data", dataBuilderSaldo)))
|
/**
|
||||||
|
* Berechnet Chart daten aller Steuerbescheide bei KW
|
||||||
.add("labels", labelsBuilder));
|
*
|
||||||
|
* <pre>
|
||||||
// Step 4: Return the JSON structure as a string
|
*
|
||||||
JsonObject chartCfg = jsonBuilder.build();
|
chartCfg = {
|
||||||
return chartCfg.toString();
|
type: 'bar',
|
||||||
}
|
data: {
|
||||||
|
datasets: [{
|
||||||
/**
|
data: [20, 10],
|
||||||
* Berechnet Chart daten aller Steuerbescheide bei KW
|
}],
|
||||||
*
|
labels: ['1', '2']
|
||||||
* <pre>
|
}
|
||||||
*
|
}
|
||||||
chartCfg = {
|
*
|
||||||
type: 'bar',
|
* </pre>
|
||||||
data: {
|
*
|
||||||
datasets: [{
|
* @return
|
||||||
data: [20, 10],
|
*/
|
||||||
}],
|
private String accumulateSteuerbescheideAbteilungByWeek() {
|
||||||
labels: ['1', '2']
|
logger.fine("accumulate steuer by Abteilung week...");
|
||||||
}
|
|
||||||
}
|
String[] colors = { "#36a2eb", "#ff6384", "#4bc0c0", "#ff9f40", "#96f", "#ffcd56", "#c9cbcf" };
|
||||||
*
|
|
||||||
* </pre>
|
List<ItemCollection> list = getSteuerbescheide();
|
||||||
*
|
Map<String, SteuerData> totalByWeek = new HashMap<>();
|
||||||
* @return
|
Calendar calendar = Calendar.getInstance();
|
||||||
*/
|
int earliestWeek = Integer.MAX_VALUE;
|
||||||
private String accumulateSteuerbescheideAbteilungByWeek() {
|
int latestWeek = Integer.MIN_VALUE;
|
||||||
logger.fine("accumulate steuer by Abteilung week...");
|
|
||||||
|
List<String> abteilungsListe = new ArrayList<>();
|
||||||
String[] colors = {
|
|
||||||
"#36a2eb",
|
// Step 1: Group total by week
|
||||||
"#ff6384",
|
for (ItemCollection steuerItemCol : list) {
|
||||||
"#4bc0c0",
|
String abteilung = steuerItemCol.getItemValueString("space.name");
|
||||||
"#ff9f40",
|
if (abteilung.isEmpty()) {
|
||||||
"#96f",
|
abteilung = "Keine Zuordnung";
|
||||||
"#ffcd56",
|
}
|
||||||
"#c9cbcf"
|
if (!abteilungsListe.contains(abteilung)) {
|
||||||
};
|
abteilungsListe.add(abteilung);
|
||||||
|
}
|
||||||
List<ItemCollection> list = getSteuerbescheide();
|
double saldo = steuerItemCol.getItemValueDouble("invoice.saldo");
|
||||||
Map<String, SteuerData> totalByWeek = new HashMap<>();
|
double total = steuerItemCol.getItemValueDouble("invoice.total.net");
|
||||||
Calendar calendar = Calendar.getInstance();
|
Date date = steuerItemCol.getItemValueDate("invoice.date");
|
||||||
int earliestWeek = Integer.MAX_VALUE;
|
|
||||||
int latestWeek = Integer.MIN_VALUE;
|
logger.fine(".... " + steuerItemCol.getItemValueString("$workflowSummary") + " = " + total);
|
||||||
|
// Get the week number and year from the date
|
||||||
List<String> abteilungsListe = new ArrayList<>();
|
calendar.setTime(date);
|
||||||
|
int weekNumber = calendar.get(Calendar.WEEK_OF_YEAR);
|
||||||
// Step 1: Group total by week
|
int year = calendar.get(Calendar.YEAR);
|
||||||
for (ItemCollection steuerItemCol : list) {
|
int yearWeek = year * 100 + weekNumber;
|
||||||
String abteilung = steuerItemCol.getItemValueString("space.name");
|
String key = abteilung + "~" + yearWeek;// Unique key Import Forest~202405
|
||||||
if (abteilung.isEmpty()) {
|
|
||||||
abteilung = "Keine Zuordnung";
|
// Accumulate the total per week
|
||||||
}
|
SteuerData steuerDataByWeek = totalByWeek.getOrDefault(key, new SteuerData());
|
||||||
if (!abteilungsListe.contains(abteilung)) {
|
double eust = getZollBySteuerBeleg(steuerItemCol, "EUST");
|
||||||
abteilungsListe.add(abteilung);
|
double zoll = getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
||||||
}
|
steuerDataByWeek.add(eust, zoll, total, saldo, abteilung);
|
||||||
double saldo = steuerItemCol.getItemValueDouble("invoice.saldo");
|
|
||||||
double total = steuerItemCol.getItemValueDouble("invoice.total.net");
|
totalByWeek.put(key, steuerDataByWeek);
|
||||||
Date date = steuerItemCol.getItemValueDate("invoice.date");
|
|
||||||
|
// Track the earliest and latest weeks
|
||||||
logger.fine(".... " + steuerItemCol.getItemValueString("$workflowSummary") + " = " + total);
|
earliestWeek = Math.min(earliestWeek, yearWeek);
|
||||||
// Get the week number and year from the date
|
latestWeek = Math.max(latestWeek, yearWeek);
|
||||||
calendar.setTime(date);
|
}
|
||||||
int weekNumber = calendar.get(Calendar.WEEK_OF_YEAR);
|
|
||||||
int year = calendar.get(Calendar.YEAR);
|
// Step 2: Prepare the JSON structure and ensure we have all weeks from earliest
|
||||||
int yearWeek = year * 100 + weekNumber;
|
// to latest
|
||||||
String key = abteilung + "~" + yearWeek;// Unique key Import Forest~202405
|
JsonArrayBuilder labelsBuilder = Json.createArrayBuilder();
|
||||||
|
Calendar startCal = Calendar.getInstance();
|
||||||
// Accumulate the total per week
|
startCal.set(Calendar.YEAR, earliestWeek / 100);
|
||||||
SteuerData steuerDataByWeek = totalByWeek.getOrDefault(key, new SteuerData());
|
startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
|
||||||
double eust = getZollBySteuerBeleg(steuerItemCol, "EUST");
|
|
||||||
double zoll = getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
Calendar endCal = Calendar.getInstance();
|
||||||
steuerDataByWeek.add(eust, zoll, total, saldo, abteilung);
|
endCal.set(Calendar.YEAR, latestWeek / 100);
|
||||||
|
endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
|
||||||
totalByWeek.put(key, steuerDataByWeek);
|
|
||||||
|
// Build labels - je eines pro woche
|
||||||
// Track the earliest and latest weeks
|
while (!startCal.after(endCal)) {
|
||||||
earliestWeek = Math.min(earliestWeek, yearWeek);
|
int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
|
||||||
latestWeek = Math.max(latestWeek, yearWeek);
|
int year = startCal.get(Calendar.YEAR);
|
||||||
}
|
labelsBuilder.add(weekNumber + "/" + year); // Label as 'week/year'
|
||||||
|
// Move to the next week
|
||||||
// Step 2: Prepare the JSON structure and ensure we have all weeks from earliest
|
startCal.add(Calendar.WEEK_OF_YEAR, 1);
|
||||||
// to latest
|
}
|
||||||
JsonArrayBuilder labelsBuilder = Json.createArrayBuilder();
|
|
||||||
Calendar startCal = Calendar.getInstance();
|
// Step 3: Baue die Balken pro abrteilung
|
||||||
startCal.set(Calendar.YEAR, earliestWeek / 100);
|
JsonArrayBuilder datasets = Json.createArrayBuilder();
|
||||||
startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
|
|
||||||
|
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder().add("type", "bar");
|
||||||
Calendar endCal = Calendar.getInstance();
|
|
||||||
endCal.set(Calendar.YEAR, latestWeek / 100);
|
JsonObjectBuilder dataDing = Json.createObjectBuilder();
|
||||||
endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
|
int iColor = 0;
|
||||||
|
for (String _abteilung : abteilungsListe) {
|
||||||
// Build labels - je eines pro woche
|
JsonArrayBuilder dataBuilderTotals = Json.createArrayBuilder();
|
||||||
while (!startCal.after(endCal)) {
|
|
||||||
int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
|
startCal = Calendar.getInstance();
|
||||||
int year = startCal.get(Calendar.YEAR);
|
startCal.set(Calendar.YEAR, earliestWeek / 100);
|
||||||
labelsBuilder.add(weekNumber + "/" + year); // Label as 'week/year'
|
startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
|
||||||
// Move to the next week
|
|
||||||
startCal.add(Calendar.WEEK_OF_YEAR, 1);
|
endCal = Calendar.getInstance();
|
||||||
}
|
endCal.set(Calendar.YEAR, latestWeek / 100);
|
||||||
|
endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
|
||||||
// Step 3: Baue die Balken pro abrteilung
|
|
||||||
JsonArrayBuilder datasets = Json.createArrayBuilder();
|
while (!startCal.after(endCal)) {
|
||||||
|
int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
|
||||||
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder()
|
int year = startCal.get(Calendar.YEAR);
|
||||||
.add("type", "bar");
|
int yearWeek = year * 100 + weekNumber;
|
||||||
|
String key = _abteilung + "~" + yearWeek;// Unique key Import Forest~202405
|
||||||
JsonObjectBuilder dataDing = Json.createObjectBuilder();
|
// Add the total for the week or 0.0 if no data
|
||||||
int iColor = 0;
|
SteuerData steuerData = totalByWeek.getOrDefault(key, new SteuerData());
|
||||||
for (String _abteilung : abteilungsListe) {
|
logger.fine(" " + yearWeek + "=" + steuerData.total);
|
||||||
JsonArrayBuilder dataBuilderTotals = Json.createArrayBuilder();
|
dataBuilderTotals.add(steuerData.total);
|
||||||
|
// Move to the next week
|
||||||
startCal = Calendar.getInstance();
|
startCal.add(Calendar.WEEK_OF_YEAR, 1);
|
||||||
startCal.set(Calendar.YEAR, earliestWeek / 100);
|
}
|
||||||
startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
|
|
||||||
|
datasets.add(Json.createObjectBuilder() // First dataset for 'tax'
|
||||||
endCal = Calendar.getInstance();
|
.add("label", _abteilung).add("backgroundColor", colors[iColor]).add("borderWidth", 1)
|
||||||
endCal.set(Calendar.YEAR, latestWeek / 100);
|
.add("data", dataBuilderTotals));
|
||||||
endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
|
|
||||||
|
iColor++;
|
||||||
while (!startCal.after(endCal)) {
|
if (iColor > colors.length) {
|
||||||
int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
|
iColor = 0;
|
||||||
int year = startCal.get(Calendar.YEAR);
|
}
|
||||||
int yearWeek = year * 100 + weekNumber;
|
}
|
||||||
String key = _abteilung + "~" + yearWeek;// Unique key Import Forest~202405
|
|
||||||
// Add the total for the week or 0.0 if no data
|
dataDing.add("datasets", datasets);
|
||||||
SteuerData steuerData = totalByWeek.getOrDefault(key, new SteuerData());
|
dataDing.add("labels", labelsBuilder);
|
||||||
logger.fine(" " + yearWeek + "=" + steuerData.total);
|
|
||||||
dataBuilderTotals.add(steuerData.total);
|
jsonBuilder.add("data", dataDing);
|
||||||
// Move to the next week
|
|
||||||
startCal.add(Calendar.WEEK_OF_YEAR, 1);
|
// Step 4: Return the JSON structure as a string
|
||||||
}
|
JsonObject chartCfg = jsonBuilder.build();
|
||||||
|
return chartCfg.toString();
|
||||||
datasets.add(Json.createObjectBuilder() // First dataset for 'tax'
|
}
|
||||||
.add("label", _abteilung)
|
|
||||||
.add("backgroundColor", colors[iColor])
|
/**
|
||||||
.add("borderWidth", 1)
|
* Helper method to hold zoll and eust totals in an object. Needed to build
|
||||||
.add("data", dataBuilderTotals));
|
* totals per week.
|
||||||
|
*/
|
||||||
iColor++;
|
class SteuerData {
|
||||||
if (iColor > colors.length) {
|
double total = 0.0;
|
||||||
iColor = 0;
|
double zoll = 0.0;
|
||||||
}
|
double eust = 0.0;
|
||||||
}
|
double saldo = 0.0;
|
||||||
|
String abteilung = "";
|
||||||
dataDing.add("datasets", datasets);
|
|
||||||
dataDing.add("labels", labelsBuilder);
|
public SteuerData() {
|
||||||
|
// default constructor
|
||||||
jsonBuilder.add("data", dataDing);
|
}
|
||||||
|
|
||||||
// Step 4: Return the JSON structure as a string
|
/**
|
||||||
JsonObject chartCfg = jsonBuilder.build();
|
* Adds new zoll and eust values and updates the total
|
||||||
return chartCfg.toString();
|
*
|
||||||
}
|
* @param eustNew eust value to be added
|
||||||
|
* @param zollNew zoll value to be added
|
||||||
/**
|
*/
|
||||||
* Helper method to hold zoll and eust totals in an object. Needed to build
|
public void add(double eustNew, double zollNew, double totalNew, double saldoNew, String abteilungNew) {
|
||||||
* totals per week.
|
eust = eust + eustNew;
|
||||||
*/
|
zoll = zoll + zollNew;
|
||||||
class SteuerData {
|
saldo = saldo + saldoNew;
|
||||||
double total = 0.0;
|
total = total + totalNew;
|
||||||
double zoll = 0.0;
|
abteilung = abteilungNew;
|
||||||
double eust = 0.0;
|
}
|
||||||
double saldo = 0.0;
|
|
||||||
String abteilung = "";
|
}
|
||||||
|
|
||||||
public SteuerData() {
|
|
||||||
// default constructor
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds new zoll and eust values and updates the total
|
|
||||||
*
|
|
||||||
* @param eustNew eust value to be added
|
|
||||||
* @param zollNew zoll value to be added
|
|
||||||
*/
|
|
||||||
public void add(double eustNew, double zollNew, double totalNew, double saldoNew, String abteilungNew) {
|
|
||||||
eust = eust + eustNew;
|
|
||||||
zoll = zoll + zollNew;
|
|
||||||
saldo = saldo + saldoNew;
|
|
||||||
total = total + totalNew;
|
|
||||||
abteilung = abteilungNew;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,274 +32,260 @@ import jakarta.inject.Inject;
|
||||||
* Textblock und fügt die offenen Steuerbescheid Daten ein
|
* Textblock und fügt die offenen Steuerbescheid Daten ein
|
||||||
*
|
*
|
||||||
* Der Adapter wird im Modell wie folgt konfiguriert
|
* Der Adapter wird im Modell wie folgt konfiguriert
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<steuerbescheide name="excel-export">
|
<steuerbescheide name="excel-export">
|
||||||
<textblock>textblock-ref</textblock>
|
<textblock>textblock-ref</textblock>
|
||||||
<template>filename</template>
|
<template>filename</template>
|
||||||
<targetname>filename</targetname>
|
<targetname>filename</targetname>
|
||||||
</steuerbescheide>
|
</steuerbescheide>
|
||||||
}
|
}
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
|
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
|
||||||
* (siehe POIFineReplaceAdapter).
|
* (siehe POIFineReplaceAdapter).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter kopiert die Steuerbescheiddaten in neue Zeilen, welche ab
|
* Der Adapter kopiert die Steuerbescheiddaten in neue Zeilen, welche ab
|
||||||
* Zeilennummer
|
* Zeilennummer 16 eingefügt werden.
|
||||||
* 16 eingefügt werden.
|
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
|
public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(AGLAnalyticExcelAdapter.class.getName());
|
private static Logger logger = Logger.getLogger(AGLAnalyticExcelAdapter.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
WorkflowService workflowService;
|
WorkflowService workflowService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
InvoiceService opListExportService;
|
InvoiceService opListExportService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DocumentService documentService;
|
DocumentService documentService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ConfigService configService;
|
ConfigService configService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Zahlungsavis and adds a reference
|
* This method finds or create the Zahlungsavis and adds a reference
|
||||||
* ($workitemref) to the current invoice.
|
* ($workitemref) to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection execute(ItemCollection document, ItemCollection event)
|
public ItemCollection execute(ItemCollection document, ItemCollection event)
|
||||||
throws AdapterException, PluginException {
|
throws AdapterException, PluginException {
|
||||||
|
|
||||||
// ermittle die Hauptwährungen
|
// ermittle die Hauptwährungen
|
||||||
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
||||||
List<String> currencyList = configItemCollection.getItemValue("currency.out");
|
List<String> currencyList = configItemCollection.getItemValue("currency.out");
|
||||||
if (currencyList == null || currencyList.size() < 2) {
|
if (currencyList == null || currencyList.size() < 2) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
"missing Currency configuration - please check parameters");
|
||||||
"missing Currency configuration - please check parameters");
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the Steuerbescheide options
|
|
||||||
ItemCollection steuerbescheideConfig = workflowService.evalWorkflowResult(event, "steuerbescheide",
|
|
||||||
document,
|
|
||||||
false);
|
|
||||||
if (steuerbescheideConfig == null || !steuerbescheideConfig.hasItem("excel-export")) {
|
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), CONFIG_ERROR,
|
|
||||||
"missing Steuerbescheide configuration in model event - please check model configuration");
|
|
||||||
}
|
|
||||||
List<String> excelDefList = steuerbescheideConfig.getItemValue("excel-export");
|
|
||||||
ItemCollection excelDefCollection = XMLParser.parseItemStructure(excelDefList.get(0));
|
|
||||||
|
|
||||||
String textblock = excelDefCollection.getItemValueString("textblock");
|
|
||||||
String template = excelDefCollection.getItemValueString("template");
|
|
||||||
String targetName = excelDefCollection.getItemValueString("target-name");
|
|
||||||
|
|
||||||
// adapt text....
|
|
||||||
targetName = workflowService.adaptText(targetName, document);
|
|
||||||
|
|
||||||
try {
|
|
||||||
appendExcelTemplate(document, textblock, template, targetName);
|
|
||||||
insertInvoiceRows(document, targetName);
|
|
||||||
|
|
||||||
logger.info("... loading poi configuration..");
|
|
||||||
// Process POI instructions
|
|
||||||
// read the config
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
List<String> replaceDevList = poiConfig.getItemValue("findreplace");
|
|
||||||
String eval = poiConfig.getItemValueString("eval");
|
|
||||||
|
|
||||||
logger.info("... update template with normal poi information..");
|
|
||||||
this.updateFileData(document.getFileData(targetName), document, replaceDevList, eval);
|
|
||||||
|
|
||||||
} catch (PluginException | IOException | QueryException e) {
|
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"failed to update steuerbescheide: " + e.getMessage());
|
|
||||||
}
|
|
||||||
logger.info("... completed!");
|
|
||||||
return document;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// read the Steuerbescheide options
|
||||||
* This helper method inserts a row for each invoice at row 16
|
ItemCollection steuerbescheideConfig = workflowService.evalWorkflowResult(event, "steuerbescheide", document,
|
||||||
* into the excel template file
|
false);
|
||||||
* <p>
|
if (steuerbescheideConfig == null || !steuerbescheideConfig.hasItem("excel-export")) {
|
||||||
* The method copies the Row A16 as a reference row
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||||
* <p>
|
"missing Steuerbescheide configuration in model event - please check model configuration");
|
||||||
* The named cell 'TOTAL' should contain the summary formula. It will be
|
}
|
||||||
* evaluated at the end.
|
List<String> excelDefList = steuerbescheideConfig.getItemValue("excel-export");
|
||||||
*
|
ItemCollection excelDefCollection = XMLParser.parseItemStructure(excelDefList.get(0));
|
||||||
* @throws PluginException
|
|
||||||
* @throws QueryException
|
|
||||||
*/
|
|
||||||
private void insertInvoiceRows(ItemCollection document, String fileName)
|
|
||||||
throws PluginException, QueryException {
|
|
||||||
|
|
||||||
// load dummy rechnungen
|
String textblock = excelDefCollection.getItemValueString("textblock");
|
||||||
List<ItemCollection> invoices = loadSteuerbescheide();
|
String template = excelDefCollection.getItemValueString("template");
|
||||||
|
String targetName = excelDefCollection.getItemValueString("target-name");
|
||||||
|
|
||||||
FileData fileData = document.getFileData(fileName);
|
// adapt text....
|
||||||
|
targetName = workflowService.adaptText(targetName, document);
|
||||||
|
|
||||||
// load XSSFWorkbook
|
try {
|
||||||
XSSFWorkbook doc = null;
|
appendExcelTemplate(document, textblock, template, targetName);
|
||||||
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
|
insertInvoiceRows(document, targetName);
|
||||||
doc = new XSSFWorkbook(imputStream);
|
|
||||||
// NOTE: we only take the first sheet !
|
|
||||||
XSSFSheet sheet = doc.getSheetAt(0);
|
|
||||||
CellReference invoiceRefCell = new CellReference("A11");
|
|
||||||
XSSFRow referenceRowInvoice = sheet.getRow(invoiceRefCell.getRow());
|
|
||||||
int referenceRowPos = 10;
|
|
||||||
int rowPos = referenceRowPos;
|
|
||||||
int lastRow = 2999;
|
|
||||||
logger.finest("Last rownum=" + lastRow);
|
|
||||||
|
|
||||||
// jetzt füge alle Rechnungen an.
|
logger.info("... loading poi configuration..");
|
||||||
int totalRowCount = invoices.size();
|
// Process POI instructions
|
||||||
sheet.shiftRows(referenceRowPos, lastRow, totalRowCount, true, true);
|
// read the config
|
||||||
for (ItemCollection invoice : invoices) {
|
ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", document, false);
|
||||||
logger.fine("......add invoice " + invoice.getUniqueID());
|
if (poiConfig == null || !poiConfig.hasItem("findreplace")) {
|
||||||
// now create a new line..
|
throw new PluginException(POIFindReplaceAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||||
XSSFRow row = sheet.createRow(rowPos);
|
"missing poi configuration");
|
||||||
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
|
}
|
||||||
// insert values
|
List<String> replaceDevList = poiConfig.getItemValue("findreplace");
|
||||||
row.getCell(0)
|
String eval = poiConfig.getItemValueString("eval");
|
||||||
.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)
|
|
||||||
.setCellValue(invoice.getItemValueDate("invoice.date"));
|
|
||||||
row.getCell(3, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
||||||
.setCellValue(invoice.getItemValueDate("invoice.booking_date"));
|
|
||||||
|
|
||||||
// Änderung Frau Mwangi am 5.12.2025
|
logger.info("... update template with normal poi information..");
|
||||||
// Nun soll anstatt des Departments der Anmelder ausgegeben werden
|
this.updateFileData(document.getFileData(targetName), document, replaceDevList, eval);
|
||||||
// row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
||||||
// .setCellValue(invoice.getItemValueString("space.name"));
|
|
||||||
row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
||||||
.setCellValue(invoice.getItemValueString("steuer.anmelder"));
|
|
||||||
|
|
||||||
row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
} catch (PluginException | IOException | QueryException e) {
|
||||||
.setCellValue(invoice.getItemValueString("invoice.text"));
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
row.getCell(6, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
"failed to update steuerbescheide: " + e.getMessage());
|
||||||
.setCellValue(invoice.getItemValueString("invoice.atc.number"));
|
}
|
||||||
row.getCell(7, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
logger.info("... completed!");
|
||||||
.setCellValue(invoice.getItemValueDouble("invoice.total.net"));
|
return document;
|
||||||
row.getCell(8, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
}
|
||||||
.setCellValue(invoice.getItemValueDouble("invoice.saldo"));
|
|
||||||
row.getCell(9, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
||||||
.setCellValue(invoice.getItemValueDouble("steuer.eust"));
|
|
||||||
row.getCell(10, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
||||||
.setCellValue(invoice.getItemValueDate("steuer.eust.due"));
|
|
||||||
row.getCell(11, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
||||||
.setCellValue(invoice.getItemValueDouble("steuer.zoll"));
|
|
||||||
row.getCell(12, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
||||||
.setCellValue(invoice.getItemValueDate("steuer.zoll.due"));
|
|
||||||
|
|
||||||
rowPos++;
|
/**
|
||||||
}
|
* 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>
|
||||||
|
* The named cell 'TOTAL' should contain the summary formula. It will be
|
||||||
|
* evaluated at the end.
|
||||||
|
*
|
||||||
|
* @throws PluginException
|
||||||
|
* @throws QueryException
|
||||||
|
*/
|
||||||
|
private void insertInvoiceRows(ItemCollection document, String fileName) throws PluginException, QueryException {
|
||||||
|
|
||||||
// Leerzeile
|
// load dummy rechnungen
|
||||||
// categoryRow = sheet.createRow(rowPos);
|
List<ItemCollection> invoices = loadSteuerbescheide();
|
||||||
rowPos++;
|
|
||||||
|
|
||||||
// write back the file
|
FileData fileData = document.getFileData(fileName);
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
||||||
doc.write(byteArrayOutputStream);
|
|
||||||
|
|
||||||
byte[] newContent = byteArrayOutputStream.toByteArray();
|
// load XSSFWorkbook
|
||||||
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
|
XSSFWorkbook doc = null;
|
||||||
null);
|
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
|
||||||
// update the fileData
|
doc = new XSSFWorkbook(imputStream);
|
||||||
document.addFileData(fileDataNew);
|
// NOTE: we only take the first sheet !
|
||||||
|
XSSFSheet sheet = doc.getSheetAt(0);
|
||||||
|
CellReference invoiceRefCell = new CellReference("A11");
|
||||||
|
XSSFRow referenceRowInvoice = sheet.getRow(invoiceRefCell.getRow());
|
||||||
|
int referenceRowPos = 10;
|
||||||
|
int rowPos = referenceRowPos;
|
||||||
|
int lastRow = 2999;
|
||||||
|
logger.finest("Last rownum=" + lastRow);
|
||||||
|
|
||||||
logger.finest("......new document added");
|
// jetzt füge alle Rechnungen an.
|
||||||
|
int totalRowCount = invoices.size();
|
||||||
|
sheet.shiftRows(referenceRowPos, lastRow, totalRowCount, true, true);
|
||||||
|
for (ItemCollection invoice : invoices) {
|
||||||
|
logger.fine("......add invoice " + invoice.getUniqueID());
|
||||||
|
// now create a new line..
|
||||||
|
XSSFRow row = sheet.createRow(rowPos);
|
||||||
|
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
|
||||||
|
// insert values
|
||||||
|
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)
|
||||||
|
.setCellValue(invoice.getItemValueDate("invoice.date"));
|
||||||
|
row.getCell(3, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueDate("invoice.booking_date"));
|
||||||
|
|
||||||
|
// Änderung Frau Mwangi am 5.12.2025
|
||||||
|
// Nun soll anstatt des Departments der Anmelder ausgegeben werden
|
||||||
|
// row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
// .setCellValue(invoice.getItemValueString("space.name"));
|
||||||
|
row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueString("steuer.anmelder"));
|
||||||
|
|
||||||
|
row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueString("invoice.text"));
|
||||||
|
row.getCell(6, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueString("invoice.atc.number"));
|
||||||
|
row.getCell(7, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueDouble("invoice.total.net"));
|
||||||
|
row.getCell(8, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueDouble("invoice.saldo"));
|
||||||
|
row.getCell(9, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueDouble("steuer.eust"));
|
||||||
|
row.getCell(10, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueDate("steuer.eust.due"));
|
||||||
|
row.getCell(11, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueDouble("steuer.zoll"));
|
||||||
|
row.getCell(12, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
.setCellValue(invoice.getItemValueDate("steuer.zoll.due"));
|
||||||
|
|
||||||
|
rowPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leerzeile
|
||||||
|
// categoryRow = sheet.createRow(rowPos);
|
||||||
|
rowPos++;
|
||||||
|
|
||||||
|
// write back the file
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
doc.write(byteArrayOutputStream);
|
||||||
|
|
||||||
|
byte[] newContent = byteArrayOutputStream.toByteArray();
|
||||||
|
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,
|
||||||
|
"failed to update opliste: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
if (doc != null) {
|
||||||
|
try {
|
||||||
|
doc.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
logger.severe("Failed to close workbook: " + e.getMessage());
|
||||||
InvoiceService.ERROR_CONFIG,
|
e.printStackTrace();
|
||||||
"failed to update opliste: " + e.getMessage());
|
|
||||||
} finally {
|
|
||||||
if (doc != null) {
|
|
||||||
try {
|
|
||||||
doc.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.severe("Failed to close workbook: " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method loads a text-block for a specified ref and appends the named
|
||||||
|
* fileData object of this document.
|
||||||
|
*
|
||||||
|
* @param document
|
||||||
|
* @throws PluginException
|
||||||
|
*/
|
||||||
|
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,
|
||||||
|
"invalid steuerbescheide configuration in model event - textblock/template reference not defined!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// load the text block
|
||||||
* This method loads a text-block for a specified ref and appends the named
|
FileData fileData = opListExportService.loadTextBlockFileData(textblockRef, template);
|
||||||
* fileData object of this document.
|
|
||||||
*
|
|
||||||
* @param document
|
|
||||||
* @throws PluginException
|
|
||||||
*/
|
|
||||||
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,
|
|
||||||
"invalid steuerbescheide configuration in model event - textblock/template reference not defined!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the text block
|
|
||||||
FileData fileData = opListExportService.loadTextBlockFileData(textblockRef, template);
|
|
||||||
|
|
||||||
// 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!");
|
|
||||||
}
|
|
||||||
fileData.setName(targetName);
|
|
||||||
// append document
|
|
||||||
logger.info("...append new steuerbescheide Template: " + targetName);
|
|
||||||
document.addFileData(fileData);
|
|
||||||
|
|
||||||
|
// 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!");
|
||||||
}
|
}
|
||||||
|
fileData.setName(targetName);
|
||||||
|
// append document
|
||||||
|
logger.info("...append new steuerbescheide Template: " + targetName);
|
||||||
|
document.addFileData(fileData);
|
||||||
|
|
||||||
/**
|
}
|
||||||
* Diese Methode läd alle offenen Steuerbescheide
|
|
||||||
*
|
/**
|
||||||
* @return
|
* Diese Methode läd alle offenen Steuerbescheide
|
||||||
*/
|
*
|
||||||
private List<ItemCollection> loadSteuerbescheide() {
|
* @return
|
||||||
List<ItemCollection> result = new ArrayList<>();
|
*/
|
||||||
try {
|
private List<ItemCollection> loadSteuerbescheide() {
|
||||||
result = documentService.find(
|
List<ItemCollection> result = new ArrayList<>();
|
||||||
"$modelversion:steuerbescheid-* AND type:workitem", 9999, 0,
|
try {
|
||||||
"invoice.number", false);
|
result = documentService.find("$modelversion:steuerbescheid-* AND type:workitem", 9999, 0, "invoice.number",
|
||||||
} catch (QueryException e) {
|
false);
|
||||||
e.printStackTrace();
|
} catch (QueryException e) {
|
||||||
}
|
e.printStackTrace();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -35,30 +35,29 @@ import jakarta.inject.Inject;
|
||||||
* Textblock und fügt die offenen Recnungen ein
|
* Textblock und fügt die offenen Recnungen ein
|
||||||
*
|
*
|
||||||
* Der Adapter wird im Modell wie folgt konfiguriert
|
* Der Adapter wird im Modell wie folgt konfiguriert
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<soa name="excel-export">
|
<soa name="excel-export">
|
||||||
<textblock>textblock-ref</textblock>
|
<textblock>textblock-ref</textblock>
|
||||||
<template>filename</template>
|
<template>filename</template>
|
||||||
<targetname>filename</targetname>
|
<targetname>filename</targetname>
|
||||||
</soa>
|
</soa>
|
||||||
}
|
}
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
|
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
|
||||||
* (siehe POIFineReplaceAdapter).
|
* (siehe POIFineReplaceAdapter).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter kopiert die ausgangsrechnungen in neue Zeilen, welche ab
|
* Der Adapter kopiert die ausgangsrechnungen in neue Zeilen, welche ab
|
||||||
* Zeilennummer
|
* Zeilennummer 16 eingefügt werden.
|
||||||
* 16 eingefügt werden.
|
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -80,7 +79,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method
|
* This method
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -92,9 +91,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
List<String> currencyList = invoiceService.getCurrenciesOut();
|
List<String> currencyList = invoiceService.getCurrenciesOut();
|
||||||
|
|
||||||
// read the options
|
// read the options
|
||||||
ItemCollection ausgangsrechnungConfig = workflowService.evalWorkflowResult(event, "soa",
|
ItemCollection ausgangsrechnungConfig = workflowService.evalWorkflowResult(event, "soa", document, false);
|
||||||
document,
|
|
||||||
false);
|
|
||||||
if (ausgangsrechnungConfig == null || !ausgangsrechnungConfig.hasItem("excel-export")) {
|
if (ausgangsrechnungConfig == null || !ausgangsrechnungConfig.hasItem("excel-export")) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapterDebitor.class.getSimpleName(), CONFIG_ERROR,
|
throw new PluginException(AGLAnalyticExcelAdapterDebitor.class.getSimpleName(), CONFIG_ERROR,
|
||||||
"missing soa configuration in model event - please check model configuration");
|
"missing soa configuration in model event - please check model configuration");
|
||||||
|
|
@ -129,14 +126,12 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
doc.write(byteArrayOutputStream);
|
doc.write(byteArrayOutputStream);
|
||||||
|
|
||||||
byte[] newContent = byteArrayOutputStream.toByteArray();
|
byte[] newContent = byteArrayOutputStream.toByteArray();
|
||||||
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
|
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
|
||||||
null);
|
|
||||||
document.addFileData(fileDataNew);
|
document.addFileData(fileDataNew);
|
||||||
logger.finest("......new document added");
|
logger.finest("......new document added");
|
||||||
|
|
||||||
} catch (IOException | QueryException e) {
|
} catch (IOException | QueryException e) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"failed to update opliste: " + e.getMessage());
|
"failed to update opliste: " + e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
|
|
@ -153,8 +148,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
processPOIUpdate(document, event, targetName);
|
processPOIUpdate(document, event, targetName);
|
||||||
|
|
||||||
} catch (PluginException e) {
|
} catch (PluginException e) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"failed to update steuerbescheide: " + e.getMessage());
|
"failed to update steuerbescheide: " + e.getMessage());
|
||||||
}
|
}
|
||||||
logger.info("... completed!");
|
logger.info("... completed!");
|
||||||
|
|
@ -166,7 +160,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
* the Total and Saldo Colum for each currency
|
* the Total and Saldo Colum for each currency
|
||||||
*
|
*
|
||||||
* The template provided only the columns for the first currency.
|
* The template provided only the columns for the first currency.
|
||||||
*
|
*
|
||||||
* @param sheet
|
* @param sheet
|
||||||
* @param currencyList
|
* @param currencyList
|
||||||
*/
|
*/
|
||||||
|
|
@ -201,7 +195,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode die das fuehrende K/D aus der Debitorennummer entfernt
|
* Hilfsmethode die das fuehrende K/D aus der Debitorennummer entfernt
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getDbtNr(ItemCollection workitem) {
|
private String getDbtNr(ItemCollection workitem) {
|
||||||
|
|
@ -213,14 +207,14 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper method inserts a row for each invoice at row 16
|
* This helper method inserts a row for each invoice at row 16 into the excel
|
||||||
* into the excel template file
|
* template file
|
||||||
* <p>
|
* <p>
|
||||||
* The method copies the Row A16 as a reference row
|
* The method copies the Row A16 as a reference row
|
||||||
* <p>
|
* <p>
|
||||||
* The named cell 'TOTAL' should contain the summary formula. It will be
|
* The named cell 'TOTAL' should contain the summary formula. It will be
|
||||||
* evaluated at the end.
|
* evaluated at the end.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*/
|
*/
|
||||||
|
|
@ -249,8 +243,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
XSSFRow row = sheet.createRow(rowPos);
|
XSSFRow row = sheet.createRow(rowPos);
|
||||||
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
|
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
|
||||||
// insert values
|
// insert values
|
||||||
row.getCell(0)
|
row.getCell(0).setCellValue(invoice.getItemValueDate("$created"));
|
||||||
.setCellValue(invoice.getItemValueDate("$created"));
|
|
||||||
row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
.setCellValue(invoice.getItemValueString("invoice.number"));
|
.setCellValue(invoice.getItemValueString("invoice.number"));
|
||||||
row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
||||||
|
|
@ -293,7 +286,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Findet die Total Spalte für eine Währung
|
* Findet die Total Spalte für eine Währung
|
||||||
*
|
*
|
||||||
* @param currency
|
* @param currency
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -313,17 +306,15 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method loads a text-block for a specified ref and appends the named
|
* This method loads a text-block for a specified ref and appends the named
|
||||||
* fileData object of this document.
|
* fileData object of this document.
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
|
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
|
||||||
String targetName)
|
String targetName) throws PluginException {
|
||||||
throws PluginException {
|
|
||||||
|
|
||||||
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
|
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"invalid SOA configuration in model event - textblock/template reference not defined!");
|
"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?
|
// do we found the document?
|
||||||
if (fileData == null) {
|
if (fileData == null) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
"invalid SOA configuration in model event - template=" + template + " not found!");
|
||||||
"invalid SOA configuration in model event - template=" + template
|
|
||||||
+ " not found!");
|
|
||||||
}
|
}
|
||||||
fileData.setName(targetName);
|
fileData.setName(targetName);
|
||||||
// append document
|
// append document
|
||||||
|
|
@ -346,18 +335,15 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode läd alle offenen Steuerbescheide
|
* Diese Methode läd alle offenen Steuerbescheide
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private List<ItemCollection> loadInvoices(String dbtrNumber) {
|
private List<ItemCollection> loadInvoices(String dbtrNumber) {
|
||||||
List<ItemCollection> result = new ArrayList<>();
|
List<ItemCollection> result = new ArrayList<>();
|
||||||
|
|
||||||
String query = "(type:workitem) AND dbtr.number:" + dbtrNumber
|
String query = "(type:workitem) AND dbtr.number:" + dbtrNumber + " AND $modelversion:rechnungsausgang-*";
|
||||||
+ " AND $modelversion:rechnungsausgang-*";
|
|
||||||
try {
|
try {
|
||||||
result = documentService.find(
|
result = documentService.find(query, 9999, 0, "invoice.number", false);
|
||||||
query, 9999, 0,
|
|
||||||
"invoice.number", false);
|
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,51 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.alexanderlogistics;
|
package com.alexanderlogistics;
|
||||||
|
|
||||||
import org.imixs.workflow.office.config.ConfigController;
|
import org.imixs.workflow.office.config.ConfigController;
|
||||||
|
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Custom Config Controller for TAXES and Invoice typs
|
* The Custom Config Controller for TAXES and Invoice typs
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Named("aglConfigController")
|
@Named("aglConfigController")
|
||||||
// @RequestScoped
|
// @RequestScoped
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class AGLConfigController extends ConfigController {
|
public class AGLConfigController extends ConfigController {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public AGLConfigController() {
|
public AGLConfigController() {
|
||||||
super();
|
super();
|
||||||
setName("AGL_CONFIGURATION");
|
setName("AGL_CONFIGURATION");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,433 +1,427 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.alexanderlogistics;
|
package com.alexanderlogistics;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.imixs.workflow.ItemCollection;
|
import org.imixs.workflow.ItemCollection;
|
||||||
import org.imixs.workflow.engine.DocumentService;
|
import org.imixs.workflow.engine.DocumentService;
|
||||||
import org.imixs.workflow.exceptions.AccessDeniedException;
|
import org.imixs.workflow.exceptions.AccessDeniedException;
|
||||||
import org.imixs.workflow.exceptions.QueryException;
|
import org.imixs.workflow.exceptions.QueryException;
|
||||||
import org.imixs.workflow.faces.data.WorkflowController;
|
import org.imixs.workflow.faces.data.WorkflowController;
|
||||||
import org.imixs.workflow.faces.data.WorkflowEvent;
|
import org.imixs.workflow.faces.data.WorkflowEvent;
|
||||||
|
|
||||||
import jakarta.enterprise.context.ConversationScoped;
|
import jakarta.enterprise.context.ConversationScoped;
|
||||||
import jakarta.enterprise.event.Observes;
|
import jakarta.enterprise.event.Observes;
|
||||||
import jakarta.faces.context.FacesContext;
|
import jakarta.faces.context.FacesContext;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
import jakarta.json.Json;
|
import jakarta.json.Json;
|
||||||
import jakarta.json.JsonObject;
|
import jakarta.json.JsonObject;
|
||||||
import jakarta.json.JsonObjectBuilder;
|
import jakarta.json.JsonObjectBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der BusinessPartnerController stellt Methoden für die BusinessPartner Forms
|
* Der BusinessPartnerController stellt Methoden für die BusinessPartner Forms
|
||||||
* sowie für die das Suche-Widget 'businesspartner_search' bereit.
|
* sowie für die das Suche-Widget 'businesspartner_search' bereit.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
@Named
|
@Named
|
||||||
@ConversationScoped
|
@ConversationScoped
|
||||||
public class BusinessPartnerController implements Serializable {
|
public class BusinessPartnerController implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
protected List<ItemCollection> ibanList = null;
|
protected List<ItemCollection> ibanList = null;
|
||||||
protected List<ItemCollection> invoicesOut = null;
|
protected List<ItemCollection> invoicesOut = null;
|
||||||
protected List<ItemCollection> invoicesIn = null;
|
protected List<ItemCollection> invoicesIn = null;
|
||||||
protected List<ItemCollection> dunnings = null;
|
protected List<ItemCollection> dunnings = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected WorkflowController workflowController;
|
protected WorkflowController workflowController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DocumentService documentService;
|
DocumentService documentService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BusinessPartnerService businessPartnerService;
|
BusinessPartnerService businessPartnerService;
|
||||||
|
|
||||||
private List<BusinessPartnerSearchEntry> searchResult = null;
|
private List<BusinessPartnerSearchEntry> searchResult = null;
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(BusinessPartnerController.class.getName());
|
private static Logger logger = Logger.getLogger(BusinessPartnerController.class.getName());
|
||||||
|
|
||||||
public List<ItemCollection> getInvoicesOut() {
|
public List<ItemCollection> getInvoicesOut() {
|
||||||
if (invoicesOut == null) {
|
if (invoicesOut == null) {
|
||||||
invoicesOut = new ArrayList<>();
|
invoicesOut = new ArrayList<>();
|
||||||
}
|
}
|
||||||
return invoicesOut;
|
return invoicesOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ItemCollection> getInvoicesIn() {
|
public List<ItemCollection> getInvoicesIn() {
|
||||||
if (invoicesIn == null) {
|
if (invoicesIn == null) {
|
||||||
invoicesIn = new ArrayList<>();
|
invoicesIn = new ArrayList<>();
|
||||||
}
|
}
|
||||||
return invoicesIn;
|
return invoicesIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ItemCollection> getDunnings() {
|
public List<ItemCollection> getDunnings() {
|
||||||
if (dunnings == null) {
|
if (dunnings == null) {
|
||||||
dunnings = new ArrayList<>();
|
dunnings = new ArrayList<>();
|
||||||
}
|
}
|
||||||
return dunnings;
|
return dunnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method searches a text phrase within the list of DATEV kreditoren
|
* This method searches a text phrase within the list of DATEV kreditoren
|
||||||
* <p>
|
* <p>
|
||||||
* JSF Integration:
|
* JSF Integration:
|
||||||
*
|
*
|
||||||
* {@code
|
* {@code
|
||||||
<h:commandScript name="datevSearch" action=
|
<h:commandScript name="datevSearch" action=
|
||||||
* "#{datevSearchController.searchCdtr()}"
|
* "#{datevSearchController.searchCdtr()}" render=
|
||||||
* render="autocomplete-resultlist-datev" onevent="autocompleteShowResult" />
|
* "autocomplete-resultlist-datev" onevent="autocompleteShowResult" /> }
|
||||||
* }
|
*/
|
||||||
*/
|
public void search(String options) {
|
||||||
public void search(String options) {
|
List<ItemCollection> resultList = null;
|
||||||
List<ItemCollection> resultList = null;
|
searchResult = new ArrayList<BusinessPartnerSearchEntry>();
|
||||||
searchResult = new ArrayList<BusinessPartnerSearchEntry>();
|
// get the param from faces context....
|
||||||
// get the param from faces context....
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
FacesContext fc = FacesContext.getCurrentInstance();
|
String phrase = fc.getExternalContext().getRequestParameterMap().get("phrase");
|
||||||
String phrase = fc.getExternalContext().getRequestParameterMap().get("phrase");
|
if (phrase == null) {
|
||||||
if (phrase == null) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
logger.fine("search prase '" + phrase + "'");
|
||||||
logger.fine("search prase '" + phrase + "'");
|
if (phrase == null || phrase.length() < 2) {
|
||||||
if (phrase == null || phrase.length() < 2) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
logger.fine("search for=" + phrase);
|
||||||
logger.fine("search for=" + phrase);
|
Pattern pattern = null;
|
||||||
Pattern pattern = null;
|
resultList = businessPartnerService.search(phrase);
|
||||||
resultList = businessPartnerService.search(phrase);
|
// Compile the regex pattern if available
|
||||||
// Compile the regex pattern if available
|
if (options.contains("regexPattern=")) {
|
||||||
if (options.contains("regexPattern=")) {
|
String regexPattern = options.substring(options.indexOf("regexPattern=") + 13);
|
||||||
String regexPattern = options.substring(options.indexOf("regexPattern=") + 13);
|
logger.fine("regex=" + regexPattern);
|
||||||
logger.fine("regex=" + regexPattern);
|
pattern = Pattern.compile(regexPattern);
|
||||||
pattern = Pattern.compile(regexPattern);
|
}
|
||||||
}
|
|
||||||
|
// Filter by Regex and convert ItemCollection into a BusinessPartnerSearchEntry
|
||||||
// Filter by Regex and convert ItemCollection into a BusinessPartnerSearchEntry
|
for (ItemCollection businessPartner : resultList) {
|
||||||
for (ItemCollection businessPartner : resultList) {
|
String name = businessPartner.getItemValueString("name");
|
||||||
String name = businessPartner.getItemValueString("name");
|
// Prüfen, ob der name der Regex entspricht
|
||||||
// Prüfen, ob der name der Regex entspricht
|
if (pattern != null) {
|
||||||
if (pattern != null) {
|
Matcher matcher = pattern.matcher(name);
|
||||||
Matcher matcher = pattern.matcher(name);
|
if (!matcher.matches()) {
|
||||||
if (!matcher.matches()) {
|
// Kein passendes Konto
|
||||||
// Kein passendes Konto
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
}
|
String display = businessPartner.getItemValueString("$workflowsummary");
|
||||||
String display = businessPartner.getItemValueString("$workflowsummary");
|
|
||||||
|
display = display.replace("\"", "");
|
||||||
display = display.replace("\"", "");
|
display = display.replace("'", "");
|
||||||
display = display.replace("'", "");
|
|
||||||
|
searchResult.add(new BusinessPartnerSearchEntry(name, display, buildJsonData(businessPartner)));
|
||||||
searchResult.add(new BusinessPartnerSearchEntry(name, display, buildJsonData(businessPartner)));
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* Diese Helper Method liefert true wenn in den Options von Form Part 'reRender'
|
||||||
* Diese Helper Method liefert true wenn in den Options von Form Part 'reRender'
|
* angegeben wurde. Damit löst die Suchmaske businesspartner_search.xhtml eine
|
||||||
* angegeben wurde.
|
* komplette rerender Phase der Form aus. Dies ist z.b. für den workflow
|
||||||
* Damit löst die Suchmaske businesspartner_search.xhtml eine komplette rerender
|
* 'analyse-debitor.bpmn' nützlich
|
||||||
* Phase der Form aus.
|
*
|
||||||
* Dies ist z.b. für den workflow 'analyse-debitor.bpmn' nützlich
|
* @param options
|
||||||
*
|
* @return
|
||||||
* @param options
|
*/
|
||||||
* @return
|
public boolean isRerenderMode(String options) {
|
||||||
*/
|
return options.toLowerCase().contains("rerender");
|
||||||
public boolean isRerenderMode(String options) {
|
}
|
||||||
return options.toLowerCase().contains("rerender");
|
|
||||||
}
|
/**
|
||||||
|
* Die Resultliste wird als eine Liste einen Arrays zurückgegeben. Der Erste
|
||||||
/**
|
* Eintrag
|
||||||
* Die Resultliste wird als eine Liste einen Arrays zurückgegeben. Der Erste
|
*
|
||||||
* Eintrag
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
public List<BusinessPartnerSearchEntry> getSearchResult() {
|
||||||
*/
|
return searchResult;
|
||||||
public List<BusinessPartnerSearchEntry> getSearchResult() {
|
}
|
||||||
return searchResult;
|
|
||||||
}
|
public ItemCollection getBusinessPartnerByID(String bpid) {
|
||||||
|
ItemCollection partner = businessPartnerService.getBusinessPartnerByID(bpid);
|
||||||
public ItemCollection getBusinessPartnerByID(String bpid) {
|
return partner;
|
||||||
ItemCollection partner = businessPartnerService.getBusinessPartnerByID(bpid);
|
}
|
||||||
return partner;
|
|
||||||
}
|
/**
|
||||||
|
* WorkflowEvent listener resolved additional data.
|
||||||
/**
|
*
|
||||||
* WorkflowEvent listener resolved additional data.
|
* For businesspartner the method converts the IBAN child list embeded HashMaps
|
||||||
*
|
* into ItemCollections and reconvert them before processing
|
||||||
* For businesspartner the method converts the IBAN child list embeded HashMaps
|
*
|
||||||
* into ItemCollections and reconvert them before processing
|
* for invoices the method resolve the partner.id and partner.name
|
||||||
*
|
*
|
||||||
* for invoices the method resolve the partner.id and partner.name
|
* @param workflowEvent
|
||||||
*
|
* @throws AccessDeniedException
|
||||||
* @param workflowEvent
|
*/
|
||||||
* @throws AccessDeniedException
|
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) throws AccessDeniedException {
|
||||||
*/
|
|
||||||
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) throws AccessDeniedException {
|
int eventType = workflowEvent.getEventType();
|
||||||
|
ItemCollection workitem = workflowEvent.getWorkitem();
|
||||||
int eventType = workflowEvent.getEventType();
|
if (workitem == null) {
|
||||||
ItemCollection workitem = workflowEvent.getWorkitem();
|
return;
|
||||||
if (workitem == null) {
|
}
|
||||||
return;
|
if (workitem.getModelVersion().startsWith("businesspartner-")) {
|
||||||
}
|
// reset orderItems if workItem has changed
|
||||||
if (workitem.getModelVersion().startsWith("businesspartner-")) {
|
if (WorkflowEvent.WORKITEM_CHANGED == eventType || WorkflowEvent.WORKITEM_CREATED == eventType) {
|
||||||
// reset orderItems if workItem has changed
|
// reset state
|
||||||
if (WorkflowEvent.WORKITEM_CHANGED == eventType || WorkflowEvent.WORKITEM_CREATED == eventType) {
|
ibanList = BusinessPartnerService.explodeBanks(workitem);
|
||||||
// reset state
|
loadStats(workitem);
|
||||||
ibanList = BusinessPartnerService.explodeBanks(workitem);
|
}
|
||||||
loadStats(workitem);
|
|
||||||
}
|
// before the workitem is saved we update the field txtOrderItems
|
||||||
|
if (WorkflowEvent.WORKITEM_BEFORE_PROCESS == eventType) {
|
||||||
// before the workitem is saved we update the field txtOrderItems
|
BusinessPartnerService.implodeBanks(workitem, ibanList);
|
||||||
if (WorkflowEvent.WORKITEM_BEFORE_PROCESS == eventType) {
|
}
|
||||||
BusinessPartnerService.implodeBanks(workitem, ibanList);
|
|
||||||
}
|
if (WorkflowEvent.WORKITEM_AFTER_PROCESS == eventType) {
|
||||||
|
// reset state
|
||||||
if (WorkflowEvent.WORKITEM_AFTER_PROCESS == eventType) {
|
ibanList = BusinessPartnerService.explodeBanks(workitem);
|
||||||
// reset state
|
}
|
||||||
ibanList = BusinessPartnerService.explodeBanks(workitem);
|
}
|
||||||
}
|
|
||||||
}
|
if (workitem.getModelVersion().startsWith("rechnungsausgang-")) {
|
||||||
|
// resolve partner.id and partner.name
|
||||||
if (workitem.getModelVersion().startsWith("rechnungsausgang-")) {
|
if (workitem.getItemValueString("partner.id").isEmpty()) {
|
||||||
// resolve partner.id and partner.name
|
// try to resolve the data
|
||||||
if (workitem.getItemValueString("partner.id").isEmpty()) {
|
ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
|
||||||
// try to resolve the data
|
if (bpWorkitem != null) {
|
||||||
ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
|
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
|
||||||
if (bpWorkitem != null) {
|
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
|
||||||
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
|
}
|
||||||
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
if (workitem.getModelVersion().startsWith("rechnungseingang-")) {
|
||||||
|
// resolve partner.id and partner.name
|
||||||
if (workitem.getModelVersion().startsWith("rechnungseingang-")) {
|
if (workitem.getItemValueString("partner.id").isEmpty()) {
|
||||||
// resolve partner.id and partner.name
|
// try to resolve the data
|
||||||
if (workitem.getItemValueString("partner.id").isEmpty()) {
|
ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
|
||||||
// try to resolve the data
|
if (bpWorkitem != null) {
|
||||||
ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
|
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
|
||||||
if (bpWorkitem != null) {
|
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
|
||||||
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
|
}
|
||||||
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
if (workitem.getModelVersion().startsWith("zahlungseingang-")) {
|
||||||
|
// resolve partner.id and partner.name
|
||||||
if (workitem.getModelVersion().startsWith("zahlungseingang-")) {
|
if (workitem.getItemValueString("partner.id").isEmpty()) {
|
||||||
// resolve partner.id and partner.name
|
// try to resolve the data
|
||||||
if (workitem.getItemValueString("partner.id").isEmpty()) {
|
ItemCollection bpWorkitem = getBusinessPartnerByID(
|
||||||
// try to resolve the data
|
InvoiceUtil.buildBPID(workitem.getItemValueString("dbtr.number")));
|
||||||
ItemCollection bpWorkitem = getBusinessPartnerByID(
|
if (bpWorkitem != null) {
|
||||||
InvoiceUtil.buildBPID(workitem.getItemValueString("dbtr.number")));
|
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
|
||||||
if (bpWorkitem != null) {
|
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
|
||||||
workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
|
}
|
||||||
workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Hilfsmethode die die offenen Rechnungen läd. Wird von WorktiemChanged Event
|
||||||
/**
|
* aufgerufen.
|
||||||
* Hilfsmethode die die offenen Rechnungen läd. Wird von WorktiemChanged Event
|
*
|
||||||
* aufgerufen.
|
* @param workitem
|
||||||
*
|
*/
|
||||||
* @param workitem
|
private void loadStats(ItemCollection workitem) {
|
||||||
*/
|
|
||||||
private void loadStats(ItemCollection workitem) {
|
try {
|
||||||
|
// Ausgangsrechnungen
|
||||||
try {
|
String dbtrNumber = workitem.getItemValueString("dbtr.number");
|
||||||
// Ausgangsrechnungen
|
if (!dbtrNumber.isEmpty()) {
|
||||||
String dbtrNumber = workitem.getItemValueString("dbtr.number");
|
invoicesOut = businessPartnerService.findOutgoingInvoices(dbtrNumber);
|
||||||
if (!dbtrNumber.isEmpty()) {
|
// Mahnungen
|
||||||
invoicesOut = businessPartnerService.findOutgoingInvoices(dbtrNumber);
|
String query = "(type:workitem) AND ($modelversion:mahnlauf-*) " + " AND (dbtr.number:" + dbtrNumber
|
||||||
// Mahnungen
|
+ ")";
|
||||||
String query = "(type:workitem) AND ($modelversion:mahnlauf-*) "
|
dunnings = documentService.findStubs(query, 999, 0, "invoice.number", false);
|
||||||
+ " AND (dbtr.number:" + dbtrNumber + ")";
|
}
|
||||||
dunnings = documentService.findStubs(query, 999, 0, "invoice.number", false);
|
|
||||||
}
|
// Eingangsrechnungen
|
||||||
|
String cdtrNumber = workitem.getItemValueString("cdtr.number");
|
||||||
// Eingangsrechnungen
|
if (!cdtrNumber.isEmpty()) {
|
||||||
String cdtrNumber = workitem.getItemValueString("cdtr.number");
|
String query = "(type:workitem) AND ($modelversion:rechnungseingang-*) " + " AND (cdtr.number:"
|
||||||
if (!cdtrNumber.isEmpty()) {
|
+ cdtrNumber + ")";
|
||||||
String query = "(type:workitem) AND ($modelversion:rechnungseingang-*) "
|
invoicesIn = documentService.findStubs(query, 999, 0, "invoice.number", false);
|
||||||
+ " AND (cdtr.number:" + cdtrNumber + ")";
|
}
|
||||||
invoicesIn = documentService.findStubs(query, 999, 0, "invoice.number", false);
|
|
||||||
}
|
} catch (QueryException e) {
|
||||||
|
logger.severe("failed to load stats: " + e.getMessage());
|
||||||
} catch (QueryException e) {
|
}
|
||||||
logger.severe("failed to load stats: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public List<ItemCollection> getIbanList() {
|
||||||
|
return ibanList;
|
||||||
public List<ItemCollection> getIbanList() {
|
}
|
||||||
return ibanList;
|
|
||||||
}
|
public void addIBAN() {
|
||||||
|
if (ibanList == null) {
|
||||||
public void addIBAN() {
|
ibanList = new ArrayList<ItemCollection>();
|
||||||
if (ibanList == null) {
|
}
|
||||||
ibanList = new ArrayList<ItemCollection>();
|
ItemCollection source = new ItemCollection();
|
||||||
}
|
ibanList.add(source);
|
||||||
ItemCollection source = new ItemCollection();
|
}
|
||||||
ibanList.add(source);
|
|
||||||
}
|
/**
|
||||||
|
* Removes an dbtr item from the list
|
||||||
/**
|
*
|
||||||
* Removes an dbtr item from the list
|
* @param name - name of dbtr
|
||||||
*
|
*/
|
||||||
* @param name - name of dbtr
|
public void removeIBAN(String id) {
|
||||||
*/
|
if (id != null && ibanList != null) {
|
||||||
public void removeIBAN(String id) {
|
for (ItemCollection cdtr : ibanList) {
|
||||||
if (id != null && ibanList != null) {
|
if (id.equals(cdtr.getItemValueString("id"))) {
|
||||||
for (ItemCollection cdtr : ibanList) {
|
ibanList.remove(cdtr);
|
||||||
if (id.equals(cdtr.getItemValueString("id"))) {
|
break;
|
||||||
ibanList.remove(cdtr);
|
}
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
/**
|
||||||
|
* This JSF backing method is called by businesspartner_serach.xhtml after the
|
||||||
/**
|
* user has selected a new businesspartner.
|
||||||
* This JSF backing method is called by businesspartner_serach.xhtml after the
|
* <p>
|
||||||
* user has selected a new businesspartner.
|
* The method lookups the given BusinessPartner and updates the metadata for
|
||||||
* <p>
|
* dbtr/cdtr depending on the workflow type. A form will than rerender the
|
||||||
* The method lookups the given BusinessPartner and updates the metadata for
|
* opList section.
|
||||||
* dbtr/cdtr depending on the workflow type.
|
*/
|
||||||
* A form will than rerender the opList section.
|
public void updateMetaData() {
|
||||||
*/
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
public void updateMetaData() {
|
String bpid = fc.getExternalContext().getRequestParameterMap().get("partnerID");
|
||||||
FacesContext fc = FacesContext.getCurrentInstance();
|
logger.info("....update metadata.....bpid = " + bpid);
|
||||||
String bpid = fc.getExternalContext().getRequestParameterMap().get("partnerID");
|
ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpid);
|
||||||
logger.info("....update metadata.....bpid = " + bpid);
|
if (businessPartner != null) {
|
||||||
ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpid);
|
|
||||||
if (businessPartner != null) {
|
// Eingangsrechnung
|
||||||
|
if (InvoiceUtil.isCreditorInvoice(workflowController.getWorkitem())) {
|
||||||
// Eingangsrechnung
|
workflowController.getWorkitem().setItemValue("cdtr.number",
|
||||||
if (InvoiceUtil.isCreditorInvoice(workflowController.getWorkitem())) {
|
businessPartner.getItemValueString("cdtr.number"));
|
||||||
workflowController.getWorkitem().setItemValue("cdtr.number",
|
workflowController.getWorkitem().setItemValue("cdtr.name",
|
||||||
businessPartner.getItemValueString("cdtr.number"));
|
businessPartner.getItemValueString("partner.name"));
|
||||||
workflowController.getWorkitem().setItemValue("cdtr.name",
|
workflowController.getWorkitem().setItemValue("cdtr.mail", businessPartner.getItemValue("cdtr.mail"));
|
||||||
businessPartner.getItemValueString("partner.name"));
|
}
|
||||||
workflowController.getWorkitem().setItemValue("cdtr.mail",
|
|
||||||
businessPartner.getItemValue("cdtr.mail"));
|
// Ausgangsrechnung
|
||||||
}
|
if (InvoiceUtil.isDebitorInvoice(workflowController.getWorkitem())) {
|
||||||
|
workflowController.getWorkitem().setItemValue("dbtr.number",
|
||||||
// Ausgangsrechnung
|
businessPartner.getItemValueString("dbtr.number"));
|
||||||
if (InvoiceUtil.isDebitorInvoice(workflowController.getWorkitem())) {
|
workflowController.getWorkitem().setItemValue("dbtr.name",
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.number",
|
businessPartner.getItemValueString("partner.name"));
|
||||||
businessPartner.getItemValueString("dbtr.number"));
|
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.name",
|
}
|
||||||
businessPartner.getItemValueString("partner.name"));
|
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.mail",
|
// Zahlungseingang
|
||||||
businessPartner.getItemValue("dbtr.mail"));
|
if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) {
|
||||||
}
|
workflowController.getWorkitem().setItemValue("dbtr.number",
|
||||||
|
businessPartner.getItemValueString("dbtr.number"));
|
||||||
// Zahlungseingang
|
workflowController.getWorkitem().setItemValue("dbtr.name",
|
||||||
if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) {
|
businessPartner.getItemValueString("partner.name"));
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.number",
|
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
|
||||||
businessPartner.getItemValueString("dbtr.number"));
|
}
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.name",
|
|
||||||
businessPartner.getItemValueString("partner.name"));
|
// Analyse Debitor
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.mail",
|
if (workflowController.getWorkitem().getModelVersion().startsWith("analyse-debitor")) {
|
||||||
businessPartner.getItemValue("dbtr.mail"));
|
workflowController.getWorkitem().setItemValue("dbtr.number",
|
||||||
}
|
businessPartner.getItemValueString("dbtr.number"));
|
||||||
|
workflowController.getWorkitem().setItemValue("dbtr.name",
|
||||||
// Analyse Debitor
|
businessPartner.getItemValueString("partner.name"));
|
||||||
if (workflowController.getWorkitem().getModelVersion().startsWith("analyse-debitor")) {
|
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.number",
|
}
|
||||||
businessPartner.getItemValueString("dbtr.number"));
|
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.name",
|
}
|
||||||
businessPartner.getItemValueString("partner.name"));
|
searchResult = null;
|
||||||
workflowController.getWorkitem().setItemValue("dbtr.mail",
|
|
||||||
businessPartner.getItemValue("dbtr.mail"));
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
}
|
* Hilfsmethode die eine JSON Struktur mit allen relevanten Daten für einen
|
||||||
searchResult = null;
|
* BusinessPartner erzeugt.
|
||||||
|
*
|
||||||
}
|
* @return
|
||||||
|
*/
|
||||||
/**
|
private String buildJsonData(ItemCollection businessPartner) {
|
||||||
* Hilfsmethode die eine JSON Struktur mit allen relevanten Daten für einen
|
JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). //
|
||||||
* BusinessPartner erzeugt.
|
add("name", jsonVal(businessPartner.getItemValueString("name"))). //
|
||||||
*
|
add("cdtr.number", jsonVal(businessPartner.getItemValueString("cdtr.number"))). //
|
||||||
* @return
|
add("dbtr.number", jsonVal(businessPartner.getItemValueString("dbtr.number"))). //
|
||||||
*/
|
add("partner.name", jsonVal(businessPartner.getItemValueString("partner.name")));
|
||||||
private String buildJsonData(ItemCollection businessPartner) {
|
|
||||||
JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). //
|
// get iban list
|
||||||
add("name", jsonVal(businessPartner.getItemValueString("name"))). //
|
// {iban=[Dxxxxxx1], name=[Bank 1], id=[bank1], bic=[CITIDEFF]}
|
||||||
add("cdtr.number", jsonVal(businessPartner.getItemValueString("cdtr.number"))). //
|
ibanList = BusinessPartnerService.getBanks(businessPartner);
|
||||||
add("dbtr.number", jsonVal(businessPartner.getItemValueString("dbtr.number"))). //
|
int i = 1;
|
||||||
add("partner.name", jsonVal(businessPartner.getItemValueString("partner.name")));
|
for (ItemCollection iban : ibanList) {
|
||||||
|
objectBuilder.add("iban" + 1, jsonVal(iban.getItemValueString("iban"))). //
|
||||||
// get iban list
|
add("bic" + 1, jsonVal(iban.getItemValueString("bic")));//
|
||||||
// {iban=[Dxxxxxx1], name=[Bank 1], id=[bank1], bic=[CITIDEFF]}
|
}
|
||||||
ibanList = BusinessPartnerService.getBanks(businessPartner);
|
|
||||||
int i = 1;
|
JsonObject jsonObject = objectBuilder.build();
|
||||||
for (ItemCollection iban : ibanList) {
|
|
||||||
objectBuilder.add("iban" + 1, jsonVal(iban.getItemValueString("iban"))). //
|
String jsonString = "{}";
|
||||||
add("bic" + 1, jsonVal(iban.getItemValueString("bic")));//
|
try (Writer writer = new StringWriter()) {
|
||||||
}
|
Json.createWriter(writer).write(jsonObject);
|
||||||
|
jsonString = writer.toString();
|
||||||
JsonObject jsonObject = objectBuilder.build();
|
} catch (IOException e) {
|
||||||
|
logger.warning("Unable to build json structure");
|
||||||
String jsonString = "{}";
|
}
|
||||||
try (Writer writer = new StringWriter()) {
|
return jsonString;
|
||||||
Json.createWriter(writer).write(jsonObject);
|
}
|
||||||
jsonString = writer.toString();
|
|
||||||
} catch (IOException e) {
|
/**
|
||||||
logger.warning("Unable to build json structure");
|
* Helper method to remove " and ' characters - causing problems
|
||||||
}
|
*
|
||||||
return jsonString;
|
* @param val
|
||||||
}
|
* @return
|
||||||
|
*/
|
||||||
/**
|
public static String jsonVal(String val) {
|
||||||
* Helper method to remove " and ' characters - causing problems
|
val = val.replace("\"", "");
|
||||||
*
|
val = val.replace("'", "");
|
||||||
* @param val
|
return val;
|
||||||
* @return
|
}
|
||||||
*/
|
|
||||||
public static String jsonVal(String val) {
|
}
|
||||||
val = val.replace("\"", "");
|
|
||||||
val = val.replace("'", "");
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -5,44 +5,44 @@ package com.alexanderlogistics;
|
||||||
* Sucheregenisses nach kreditoren an das Frontend. Die Klasse besteht aus einem
|
* Sucheregenisses nach kreditoren an das Frontend. Die Klasse besteht aus einem
|
||||||
* Key, einer DisplayZeile für die Darstellung und einen JSON String der
|
* Key, einer DisplayZeile für die Darstellung und einen JSON String der
|
||||||
* beliebige Daten enthalten kann.
|
* beliebige Daten enthalten kann.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BusinessPartnerSearchEntry {
|
public class BusinessPartnerSearchEntry {
|
||||||
|
|
||||||
private String key;
|
private String key;
|
||||||
private String display;
|
private String display;
|
||||||
private String data;
|
private String data;
|
||||||
|
|
||||||
public BusinessPartnerSearchEntry(String key, String display, String data) {
|
public BusinessPartnerSearchEntry(String key, String display, String data) {
|
||||||
super();
|
super();
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.display = display;
|
this.display = display;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(String key) {
|
public void setKey(String key) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplay() {
|
public String getDisplay() {
|
||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisplay(String display) {
|
public void setDisplay(String display) {
|
||||||
this.display = display;
|
this.display = display;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getData() {
|
public String getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(String data) {
|
public void setData(String data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow
|
* Imixs Workflow
|
||||||
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* http://www.imixs.org
|
* http://www.imixs.org
|
||||||
* http://java.net/projects/imixs-workflow
|
* http://java.net/projects/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -51,15 +51,15 @@ import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.annotation.security.DeclareRoles;
|
import jakarta.annotation.security.DeclareRoles;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import jakarta.annotation.security.RunAs;
|
import jakarta.annotation.security.RunAs;
|
||||||
import jakarta.ejb.Singleton;
|
import jakarta.ejb.Stateless;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der BusinessPartnerService stellt Methoden für den Zugriff auf Business
|
* Der BusinessPartnerService stellt Methoden für den Zugriff auf Business
|
||||||
* Partner bereit.
|
* Partner bereit.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||||
|
|
@ -68,7 +68,7 @@ import jakarta.inject.Inject;
|
||||||
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||||
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
||||||
@Singleton
|
@Stateless
|
||||||
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
||||||
public class BusinessPartnerService {
|
public class BusinessPartnerService {
|
||||||
|
|
||||||
|
|
@ -121,13 +121,12 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode aktualisiert das business Partner object. Sie wird von den
|
* Diese Methode aktualisiert das business Partner object. Sie wird von den
|
||||||
* Invoice Plugins genutzt.
|
* Invoice Plugins genutzt. Die Methode wirft eine PluginException falls das
|
||||||
* Die Methode wirft eine PluginException falls das BusinessPartner Objekt
|
* BusinessPartner Objekt gesperrt oder in verification ist!
|
||||||
* gesperrt oder in verification ist!
|
*
|
||||||
*
|
|
||||||
* Gleichzeitig wird bei Rechnungen in Abhängigkeit der Rechnungsart die
|
* Gleichzeitig wird bei Rechnungen in Abhängigkeit der Rechnungsart die
|
||||||
* dbtr./cdtr. items sowie mail und country aktualisiert.
|
* dbtr./cdtr. items sowie mail und country aktualisiert.
|
||||||
*
|
*
|
||||||
* @param partnerID
|
* @param partnerID
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
|
|
@ -145,8 +144,18 @@ public class BusinessPartnerService {
|
||||||
workitem.setItemValue("partner.id", partnerID);
|
workitem.setItemValue("partner.id", partnerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (partnerID == null || partnerID.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// load Business Partner
|
// load Business Partner
|
||||||
ItemCollection businessPartner = getBusinessPartnerByID(partnerID);
|
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) {
|
if (businessPartner != null) {
|
||||||
workitem.setItemValue("partner.name", businessPartner.getItemValueString("partner.name"));
|
workitem.setItemValue("partner.name", businessPartner.getItemValueString("partner.name"));
|
||||||
|
|
||||||
|
|
@ -166,13 +175,11 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
// Validate Business Partner Status!
|
// Validate Business Partner Status!
|
||||||
if (businessPartner.getTaskID() == TASK_VERIFICATION) {
|
if (businessPartner.getTaskID() == TASK_VERIFICATION) {
|
||||||
throw new PluginException(InvoicePlugin.class.getName(),
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_BUSINESSPARTNER_VERIFICATION,
|
||||||
ERROR_BUSINESSPARTNER_VERIFICATION,
|
|
||||||
"Businesspartner is in verification. Invoice can't be processed!");
|
"Businesspartner is in verification. Invoice can't be processed!");
|
||||||
}
|
}
|
||||||
if (businessPartner.getTaskID() == TASK_LOCKED) {
|
if (businessPartner.getTaskID() == TASK_LOCKED) {
|
||||||
throw new PluginException(InvoicePlugin.class.getName(),
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_BUSINESSPARTNER_LOCKED,
|
||||||
ERROR_BUSINESSPARTNER_LOCKED,
|
|
||||||
"Businesspartner is locked. Invoice can't be processed!");
|
"Businesspartner is locked. Invoice can't be processed!");
|
||||||
}
|
}
|
||||||
// update business partner status...
|
// update business partner status...
|
||||||
|
|
@ -195,7 +202,7 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the stubs of all outgoing invoices
|
* Returns the stubs of all outgoing invoices
|
||||||
*
|
*
|
||||||
* @param _dbtrNumber
|
* @param _dbtrNumber
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -224,9 +231,8 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode sucht einen Business Partner anhand seiner BPID
|
* Diese Methode sucht einen Business Partner anhand seiner BPID
|
||||||
*
|
*
|
||||||
* @param bpid
|
* @param bpid - business partner id phrase
|
||||||
* - business partner id phrase
|
|
||||||
* @return - matching business partner
|
* @return - matching business partner
|
||||||
*/
|
*/
|
||||||
public ItemCollection getBusinessPartnerByID(String bpid) {
|
public ItemCollection getBusinessPartnerByID(String bpid) {
|
||||||
|
|
@ -250,9 +256,8 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode sucht Business Partner anhand einer Suchphrase
|
* Diese Methode sucht Business Partner anhand einer Suchphrase
|
||||||
*
|
*
|
||||||
* @param phrase
|
* @param phrase - search phrase
|
||||||
* - search phrase
|
|
||||||
* @return - list of matching business partners
|
* @return - list of matching business partners
|
||||||
*/
|
*/
|
||||||
public List<ItemCollection> search(String phrase) {
|
public List<ItemCollection> search(String phrase) {
|
||||||
|
|
@ -283,7 +288,7 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Packt die Liste der Bank Details (ItemCollections) in ein Workitem
|
* Packt die Liste der Bank Details (ItemCollections) in ein Workitem
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
public static void implodeBanks(ItemCollection workitem, List<ItemCollection> ibanList) {
|
public static void implodeBanks(ItemCollection workitem, List<ItemCollection> ibanList) {
|
||||||
|
|
@ -304,7 +309,7 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enpackt die iban Map Liste von eiem Worktiem in eine Liste von ItemCollection
|
* Enpackt die iban Map Liste von eiem Worktiem in eine Liste von ItemCollection
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
public static List<ItemCollection> explodeBanks(ItemCollection workitem) {
|
public static List<ItemCollection> explodeBanks(ItemCollection workitem) {
|
||||||
|
|
@ -325,7 +330,7 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liefert die ChildItems mit den IBAN daten
|
* Liefert die ChildItems mit den IBAN daten
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -345,7 +350,7 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode übertragt neue IBAN/BIC Pare in den Kreditor Banken Bereich
|
* Diese Methode übertragt neue IBAN/BIC Pare in den Kreditor Banken Bereich
|
||||||
*
|
*
|
||||||
* @param cdtrNumber
|
* @param cdtrNumber
|
||||||
* @param iban
|
* @param iban
|
||||||
* @param bic
|
* @param bic
|
||||||
|
|
@ -374,7 +379,7 @@ public class BusinessPartnerService {
|
||||||
/**
|
/**
|
||||||
* Diese Methode gibt true zurück wenn die angegebene IBAN/BIC Kombination als
|
* Diese Methode gibt true zurück wenn die angegebene IBAN/BIC Kombination als
|
||||||
* bank bereits bekannt ist
|
* bank bereits bekannt ist
|
||||||
*
|
*
|
||||||
* @param cdtrNumber
|
* @param cdtrNumber
|
||||||
* @param iban
|
* @param iban
|
||||||
* @param bic
|
* @param bic
|
||||||
|
|
@ -386,8 +391,7 @@ public class BusinessPartnerService {
|
||||||
|
|
||||||
List<ItemCollection> bankenListe = explodeBanks(businessPartner);
|
List<ItemCollection> bankenListe = explodeBanks(businessPartner);
|
||||||
for (ItemCollection bank : bankenListe) {
|
for (ItemCollection bank : bankenListe) {
|
||||||
if (iban.equals(bank.getItemValueString("iban"))
|
if (iban.equals(bank.getItemValueString("iban")) && bic.equals(bank.getItemValueString("bic"))) {
|
||||||
&& bic.equals(bank.getItemValueString("bic"))) {
|
|
||||||
// known!
|
// known!
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,18 +25,18 @@ import jakarta.inject.Inject;
|
||||||
* <p>
|
* <p>
|
||||||
* report = report definition to transfers the workitem into the cargosoft xml
|
* report = report definition to transfers the workitem into the cargosoft xml
|
||||||
* structure
|
* structure
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<cargosoft name="report">cargosoft</cargosoft>
|
<cargosoft name="report">cargosoft</cargosoft>
|
||||||
|
|
||||||
}
|
}
|
||||||
* </pre>
|
* </pre>
|
||||||
* <p>
|
* <p>
|
||||||
* Because we also export the attachment data to cargosoft, the adaper lookups
|
* Because we also export the attachment data to cargosoft, the adaper lookups
|
||||||
* the conente of the attachment in the snapshot of the origin workitem
|
* the conente of the attachment in the snapshot of the origin workitem
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -113,8 +113,8 @@ public class CargosoftExportAdapter implements SignalAdapter {
|
||||||
// finally append the success event id
|
// finally append the success event id
|
||||||
document.event(EVENT_SUCCESS);
|
document.event(EVENT_SUCCESS);
|
||||||
|
|
||||||
} catch (PluginException | IOException
|
} catch (PluginException | IOException | jakarta.xml.bind.JAXBException
|
||||||
| jakarta.xml.bind.JAXBException | javax.xml.transform.TransformerException e) {
|
| javax.xml.transform.TransformerException e) {
|
||||||
logger.severe("cargosoft export failed: " + e.getMessage());
|
logger.severe("cargosoft export failed: " + e.getMessage());
|
||||||
document.setItemValue("cargosoft.error", e.getMessage());
|
document.setItemValue("cargosoft.error", e.getMessage());
|
||||||
document.event(EVENT_FAILURE);
|
document.event(EVENT_FAILURE);
|
||||||
|
|
@ -130,8 +130,8 @@ public class CargosoftExportAdapter implements SignalAdapter {
|
||||||
* Change 14.10.2021 - Wir senden maximal 5MB and Daten, da die Cargosoft
|
* Change 14.10.2021 - Wir senden maximal 5MB and Daten, da die Cargosoft
|
||||||
* Schnittstelle größere Datensätze mit großen Dateianhängen einfach verschluckt
|
* Schnittstelle größere Datensätze mit großen Dateianhängen einfach verschluckt
|
||||||
* ohne eine Fehlermeldugn zu liefern.
|
* ohne eine Fehlermeldugn zu liefern.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import jakarta.inject.Inject;
|
||||||
* ein neue Sequencenummer die im Hautpworkitem gespeichert wird.
|
* ein neue Sequencenummer die im Hautpworkitem gespeichert wird.
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter wird im Modell wie folgt konfiguriert
|
* Der Adapter wird im Modell wie folgt konfiguriert
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<cargosoft>
|
<cargosoft>
|
||||||
|
|
@ -41,14 +41,14 @@ import jakarta.inject.Inject;
|
||||||
<event>100</event>
|
<event>100</event>
|
||||||
<items>(?!txtworkflowhistory)(^[a-zA-Z]|^_)</items>
|
<items>(?!txtworkflowhistory)(^[a-zA-Z]|^_)</items>
|
||||||
</cargosoft>
|
</cargosoft>
|
||||||
|
|
||||||
}
|
}
|
||||||
* </pre>
|
* </pre>
|
||||||
* <p>
|
* <p>
|
||||||
* Because we also export the attachment data to cargosoft, the adaper lookups
|
* Because we also export the attachment data to cargosoft, the adaper lookups
|
||||||
* the conente of the attachment in the snapshot of the origin workitem
|
* the conente of the attachment in the snapshot of the origin workitem
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -65,7 +65,7 @@ public class CargosoftSplitAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method computes the cargosoft export data file
|
* This method computes the cargosoft export data file
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
|
|
@ -189,21 +189,21 @@ public class CargosoftSplitAdapter implements SignalAdapter {
|
||||||
* <p>
|
* <p>
|
||||||
* Example: {@code
|
* Example: {@code
|
||||||
* txttitle,txtfirstname
|
* txttitle,txtfirstname
|
||||||
*
|
*
|
||||||
* txttitle|newitem1,txtfirstname|newitem2
|
* txttitle|newitem1,txtfirstname|newitem2
|
||||||
*
|
*
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Optional also reg expressions are supported. In this case mapping of the item
|
* Optional also reg expressions are supported. In this case mapping of the item
|
||||||
* name is not supported.
|
* name is not supported.
|
||||||
* <p>
|
* <p>
|
||||||
* Example: {@code
|
* Example: {@code
|
||||||
* (^artikel$|^invoice$),txtTitel|txtNewTitel
|
* (^artikel$|^invoice$),txtTitel|txtNewTitel
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* } A reg expression must be includes in brackets.
|
* } A reg expression must be includes in brackets.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected void copyItemList(String items, ItemCollection source, ItemCollection target) {
|
protected void copyItemList(String items, ItemCollection source, ItemCollection target) {
|
||||||
// clone the field list...
|
// clone the field list...
|
||||||
|
|
|
||||||
|
|
@ -1,285 +1,283 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.alexanderlogistics;
|
package com.alexanderlogistics;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.imixs.marty.team.TeamController;
|
import org.imixs.marty.team.TeamController;
|
||||||
import org.imixs.workflow.ItemCollection;
|
import org.imixs.workflow.ItemCollection;
|
||||||
import org.imixs.workflow.office.views.SearchController;
|
import org.imixs.workflow.office.views.SearchController;
|
||||||
import org.imixs.workflow.office.views.SearchEvent;
|
import org.imixs.workflow.office.views.SearchEvent;
|
||||||
|
|
||||||
import jakarta.enterprise.context.SessionScoped;
|
import jakarta.enterprise.context.SessionScoped;
|
||||||
import jakarta.enterprise.event.Observes;
|
import jakarta.enterprise.event.Observes;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der CustomSearchController reagiert auf SeachEvents und erweitert das Search
|
* Der CustomSearchController reagiert auf SeachEvents und erweitert das Search
|
||||||
* Query um Rechnungbetrag von-bis.
|
* Query um Rechnungbetrag von-bis.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Named
|
@Named
|
||||||
@SessionScoped
|
@SessionScoped
|
||||||
// @RequestScoped
|
// @RequestScoped
|
||||||
public class CustomSearchController implements Serializable {
|
public class CustomSearchController implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(CustomSearchController.class.getName());
|
private static Logger logger = Logger.getLogger(CustomSearchController.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SearchController searchController;
|
SearchController searchController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
TeamController teamController;
|
TeamController teamController;
|
||||||
|
|
||||||
boolean isArchiveSearch = false;
|
boolean isArchiveSearch = false;
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
isArchiveSearch = true;
|
isArchiveSearch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Suche schränkt immer auf Archive und Rechnugnscontrolling ein!!
|
* Diese Suche schränkt immer auf Archive und Rechnugnscontrolling ein!!
|
||||||
*
|
*
|
||||||
* @param searchEvent
|
* @param searchEvent
|
||||||
*/
|
*/
|
||||||
public void onSearchEvent(@Observes SearchEvent searchEvent) {
|
public void onSearchEvent(@Observes SearchEvent searchEvent) {
|
||||||
|
|
||||||
if (!isArchiveSearch) {
|
if (!isArchiveSearch) {
|
||||||
// Keine Anpassung für andere Prozesse
|
// Keine Anpassung für andere Prozesse
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String query = searchEvent.getQuery();
|
String query = searchEvent.getQuery();
|
||||||
float invoiceTotal = searchEvent.getSearchFilter().getItemValueFloat("invoice.total");
|
float invoiceTotal = searchEvent.getSearchFilter().getItemValueFloat("invoice.total");
|
||||||
Date invoiceDate = searchEvent.getSearchFilter().getItemValueDate("invoice.date");
|
Date invoiceDate = searchEvent.getSearchFilter().getItemValueDate("invoice.date");
|
||||||
Date dueDate = searchEvent.getSearchFilter().getItemValueDate("invoice.duedate");
|
Date dueDate = searchEvent.getSearchFilter().getItemValueDate("invoice.duedate");
|
||||||
Date closingDate = searchEvent.getSearchFilter().getItemValueDate("invoice.closingdate");
|
Date closingDate = searchEvent.getSearchFilter().getItemValueDate("invoice.closingdate");
|
||||||
|
|
||||||
String cdtrNumber = searchEvent.getSearchFilter().getItemValueString("cdtr.number").trim();
|
String cdtrNumber = searchEvent.getSearchFilter().getItemValueString("cdtr.number").trim();
|
||||||
String invoiceType = searchEvent.getSearchFilter().getItemValueString("invoice.type");
|
String invoiceType = searchEvent.getSearchFilter().getItemValueString("invoice.type");
|
||||||
String invoiceCurrency = searchEvent.getSearchFilter().getItemValueString("invoice.currency").trim();
|
String invoiceCurrency = searchEvent.getSearchFilter().getItemValueString("invoice.currency").trim();
|
||||||
|
|
||||||
String invoiceNumber = searchEvent.getSearchFilter().getItemValueString("invoice.number");
|
String invoiceNumber = searchEvent.getSearchFilter().getItemValueString("invoice.number");
|
||||||
|
|
||||||
String paymentType = searchEvent.getSearchFilter().getItemValueString("payment.type").trim();
|
String paymentType = searchEvent.getSearchFilter().getItemValueString("payment.type").trim();
|
||||||
String sequenceNumber = searchEvent.getSearchFilter().getItemValueString("sequencenumber").trim();
|
String sequenceNumber = searchEvent.getSearchFilter().getItemValueString("sequencenumber").trim();
|
||||||
|
|
||||||
query += " (type:\"workitemarchive\") ";
|
query += " (type:\"workitemarchive\") ";
|
||||||
// process ref= Rechnugnscontorling Prozess
|
// process ref= Rechnugnscontorling Prozess
|
||||||
ItemCollection process = teamController.getProcessByName("Rechnungscontrolling");
|
ItemCollection process = teamController.getProcessByName("Rechnungscontrolling");
|
||||||
if (process == null) {
|
if (process == null) {
|
||||||
process = teamController.getProcessByName("Invoice Controlling");
|
process = teamController.getProcessByName("Invoice Controlling");
|
||||||
}
|
}
|
||||||
if (process != null) {
|
if (process != null) {
|
||||||
query += " AND ($uniqueidref:\"" + process.getUniqueID() + "\") ";
|
query += " AND ($uniqueidref:\"" + process.getUniqueID() + "\") ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoice.total
|
// invoice.total
|
||||||
if (invoiceTotal != 0) {
|
if (invoiceTotal != 0) {
|
||||||
// format form and to with at least one digit
|
// format form and to with at least one digit
|
||||||
DecimalFormat decimalFormat = new DecimalFormat("#.00");
|
DecimalFormat decimalFormat = new DecimalFormat("#.00");
|
||||||
query += " AND (invoice.total:" + decimalFormat.format(invoiceTotal) + ")";
|
query += " AND (invoice.total:" + decimalFormat.format(invoiceTotal) + ")";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoice.date
|
// invoice.date
|
||||||
if (invoiceDate != null) {
|
if (invoiceDate != null) {
|
||||||
query += " AND (invoice.date:" + CustomSearchController.getRangeDay(invoiceDate) + ")";
|
query += " AND (invoice.date:" + CustomSearchController.getRangeDay(invoiceDate) + ")";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoice.duedate
|
// invoice.duedate
|
||||||
if (dueDate != null) {
|
if (dueDate != null) {
|
||||||
query += " AND (invoice.duedate:" + CustomSearchController.getRangeDay(dueDate) + ")";
|
query += " AND (invoice.duedate:" + CustomSearchController.getRangeDay(dueDate) + ")";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoice.closingdate
|
// invoice.closingdate
|
||||||
if (closingDate != null) {
|
if (closingDate != null) {
|
||||||
query += " AND ($lasteventdate:" + CustomSearchController.getRangeMonth(closingDate) + ")";
|
query += " AND ($lasteventdate:" + CustomSearchController.getRangeMonth(closingDate) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoiceNumber != null && !invoiceNumber.isEmpty()) {
|
if (invoiceNumber != null && !invoiceNumber.isEmpty()) {
|
||||||
query += " AND (invoice.number:" + invoiceNumber + ")";
|
query += " AND (invoice.number:" + invoiceNumber + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paymentType != null && !paymentType.isEmpty()) {
|
if (paymentType != null && !paymentType.isEmpty()) {
|
||||||
query += " AND (payment.type:" + paymentType + ")";
|
query += " AND (payment.type:" + paymentType + ")";
|
||||||
}
|
}
|
||||||
if (sequenceNumber != null && !sequenceNumber.isEmpty()) {
|
if (sequenceNumber != null && !sequenceNumber.isEmpty()) {
|
||||||
query += " AND (sequencenumber:" + sequenceNumber + ")";
|
query += " AND (sequencenumber:" + sequenceNumber + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoiceCurrency != null && !invoiceCurrency.isEmpty()) {
|
if (invoiceCurrency != null && !invoiceCurrency.isEmpty()) {
|
||||||
query += " AND (invoice.currency:" + invoiceCurrency + ")";
|
query += " AND (invoice.currency:" + invoiceCurrency + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rechnungsart
|
// Rechnungsart
|
||||||
if (invoiceType != null && !"0".equals(invoiceType)) {
|
if (invoiceType != null && !"0".equals(invoiceType)) {
|
||||||
if ("1".equals(invoiceType)) {
|
if ("1".equals(invoiceType)) {
|
||||||
query += " AND ($workflowgroup:\"Rechnungseingang\" AND NOT payment.type:credit)";
|
query += " AND ($workflowgroup:\"Rechnungseingang\" AND NOT payment.type:credit)";
|
||||||
}
|
}
|
||||||
if ("2".equals(invoiceType)) {
|
if ("2".equals(invoiceType)) {
|
||||||
query += " AND ($workflowgroup:Sachrechnung)";
|
query += " AND ($workflowgroup:Sachrechnung)";
|
||||||
}
|
}
|
||||||
if ("3".equals(invoiceType)) {
|
if ("3".equals(invoiceType)) {
|
||||||
query += " AND (($workflowgroup:Rechnungseingang) AND (payment.type:credit))";
|
query += " AND (($workflowgroup:Rechnungseingang) AND (payment.type:credit))";
|
||||||
}
|
}
|
||||||
if ("4".equals(invoiceType)) {
|
if ("4".equals(invoiceType)) {
|
||||||
query += " AND ($workflowgroup:\"Gutschrift Abgleich\")";
|
query += " AND ($workflowgroup:\"Gutschrift Abgleich\")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbtr.number
|
// dbtr.number
|
||||||
if (cdtrNumber != null && !cdtrNumber.isEmpty()) {
|
if (cdtrNumber != null && !cdtrNumber.isEmpty()) {
|
||||||
cdtrNumber = cdtrNumber.trim().toUpperCase();
|
cdtrNumber = cdtrNumber.trim().toUpperCase();
|
||||||
if (!cdtrNumber.startsWith("K") && !cdtrNumber.startsWith("D")) {
|
if (!cdtrNumber.startsWith("K") && !cdtrNumber.startsWith("D")) {
|
||||||
query += " AND (cdtr.number:K" + cdtrNumber + " OR dbtr.number:" + cdtrNumber + ")";
|
query += " AND (cdtr.number:K" + cdtrNumber + " OR dbtr.number:" + cdtrNumber + ")";
|
||||||
} else {
|
} else {
|
||||||
if (cdtrNumber.startsWith("K")) {
|
if (cdtrNumber.startsWith("K")) {
|
||||||
// suche nach Kreditor (Eingangsrechnung)
|
// suche nach Kreditor (Eingangsrechnung)
|
||||||
query += " AND (cdtr.number:" + cdtrNumber + ")";
|
query += " AND (cdtr.number:" + cdtrNumber + ")";
|
||||||
} else {
|
} else {
|
||||||
// suche nach Debitor (Ausgangsrechnung)
|
// suche nach Debitor (Ausgangsrechnung)
|
||||||
if (cdtrNumber.startsWith("D")) {
|
if (cdtrNumber.startsWith("D")) {
|
||||||
cdtrNumber = cdtrNumber.substring(1);
|
cdtrNumber = cdtrNumber.substring(1);
|
||||||
}
|
}
|
||||||
query += " AND (dbtr.number:" + cdtrNumber + ")";
|
query += " AND (dbtr.number:" + cdtrNumber + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.fine("Custom Query=" + query);
|
logger.fine("Custom Query=" + query);
|
||||||
// Udpate query
|
// Udpate query
|
||||||
searchEvent.setQuery(query);
|
searchEvent.setQuery(query);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sonder AGL Lösung um im Archiv zu bleiben.
|
* Sonder AGL Lösung um im Archiv zu bleiben.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public String refreshAGLArchive() {
|
public String refreshAGLArchive() {
|
||||||
String phrase = searchController.getSearchFilter().getItemValueString("phrase");
|
String phrase = searchController.getSearchFilter().getItemValueString("phrase");
|
||||||
searchController.refreshSearch();
|
searchController.refreshSearch();
|
||||||
searchController.getSearchFilter().setItemValue("type", "workitemarchive");
|
searchController.getSearchFilter().setItemValue("type", "workitemarchive");
|
||||||
String action = "/pages/workitems/agl_archive.xhtml?faces-redirect=true&phrase=" + phrase;
|
String action = "/pages/workitems/agl_archive.xhtml?faces-redirect=true&phrase=" + phrase;
|
||||||
return action;
|
return action;
|
||||||
|
|
||||||
// String phrase =
|
// String phrase =
|
||||||
// searchController.getSearchFilter().getItemValueString("phrase");
|
// searchController.getSearchFilter().getItemValueString("phrase");
|
||||||
|
|
||||||
// searchController.getSearchFilter().setItemValue("type", "workitemarchive");
|
// searchController.getSearchFilter().setItemValue("type", "workitemarchive");
|
||||||
// try {
|
// try {
|
||||||
// phrase = URLEncoder.encode(phrase, "UTF-8");
|
// phrase = URLEncoder.encode(phrase, "UTF-8");
|
||||||
// } catch (UnsupportedEncodingException e) {
|
// } catch (UnsupportedEncodingException e) {
|
||||||
// logger.severe("unable to encode search phrase!");
|
// logger.severe("unable to encode search phrase!");
|
||||||
// e.printStackTrace();
|
// e.printStackTrace();
|
||||||
// }
|
// }
|
||||||
// String action =
|
// String action =
|
||||||
// "/pages/workitems/agl_archive.xhtml?faces-redirect=true&phrase=" + phrase;
|
// "/pages/workitems/agl_archive.xhtml?faces-redirect=true&phrase=" + phrase;
|
||||||
// searchController.setPageIndex(0);
|
// searchController.setPageIndex(0);
|
||||||
// return action;
|
// return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method reset the search filter and the search pageIndex and creates a
|
* This method reset the search filter and the search pageIndex and creates a
|
||||||
* new bookmarkable search link to the worklist including the current search
|
* new bookmarkable search link to the worklist including the current search
|
||||||
* phrase.
|
* phrase.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public String resetSearch() {
|
public String resetSearch() {
|
||||||
searchController.reset();
|
searchController.reset();
|
||||||
return refreshAGLArchive();
|
return refreshAGLArchive();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getRangeDay(Date dueDate) {
|
private static String getRangeDay(Date dueDate) {
|
||||||
// Setze die Uhrzeit auf Mitternacht (00:00)
|
// Setze die Uhrzeit auf Mitternacht (00:00)
|
||||||
Calendar startCalendar = Calendar.getInstance();
|
Calendar startCalendar = Calendar.getInstance();
|
||||||
startCalendar.setTime(dueDate);
|
startCalendar.setTime(dueDate);
|
||||||
startCalendar.set(Calendar.HOUR_OF_DAY, 0);
|
startCalendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
startCalendar.set(Calendar.MINUTE, 0);
|
startCalendar.set(Calendar.MINUTE, 0);
|
||||||
startCalendar.set(Calendar.SECOND, 0);
|
startCalendar.set(Calendar.SECOND, 0);
|
||||||
startCalendar.set(Calendar.MILLISECOND, 0);
|
startCalendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
Date startDate = startCalendar.getTime();
|
Date startDate = startCalendar.getTime();
|
||||||
|
|
||||||
// Setze die Uhrzeit auf 23:59:59.999
|
// Setze die Uhrzeit auf 23:59:59.999
|
||||||
Calendar endCalendar = Calendar.getInstance();
|
Calendar endCalendar = Calendar.getInstance();
|
||||||
endCalendar.setTime(dueDate);
|
endCalendar.setTime(dueDate);
|
||||||
endCalendar.set(Calendar.HOUR_OF_DAY, 23);
|
endCalendar.set(Calendar.HOUR_OF_DAY, 23);
|
||||||
endCalendar.set(Calendar.MINUTE, 59);
|
endCalendar.set(Calendar.MINUTE, 59);
|
||||||
endCalendar.set(Calendar.SECOND, 59);
|
endCalendar.set(Calendar.SECOND, 59);
|
||||||
endCalendar.set(Calendar.MILLISECOND, 999);
|
endCalendar.set(Calendar.MILLISECOND, 999);
|
||||||
|
|
||||||
Date endDate = endCalendar.getTime();
|
Date endDate = endCalendar.getTime();
|
||||||
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
||||||
String dateRange = "[" + dateformat.format(startDate) + " TO "
|
String dateRange = "[" + dateformat.format(startDate) + " TO " + dateformat.format(endDate) + "]";
|
||||||
+ dateformat.format(endDate) + "]";
|
|
||||||
|
return dateRange;
|
||||||
return dateRange;
|
}
|
||||||
}
|
|
||||||
|
private static String getRangeMonth(Date dueDate) {
|
||||||
private static String getRangeMonth(Date dueDate) {
|
// Setze die Uhrzeit auf Mitternacht (00:00)
|
||||||
// Setze die Uhrzeit auf Mitternacht (00:00)
|
Calendar startCalendar = Calendar.getInstance();
|
||||||
Calendar startCalendar = Calendar.getInstance();
|
startCalendar.setTime(dueDate);
|
||||||
startCalendar.setTime(dueDate);
|
startCalendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
startCalendar.set(Calendar.HOUR_OF_DAY, 0);
|
startCalendar.set(Calendar.MINUTE, 0);
|
||||||
startCalendar.set(Calendar.MINUTE, 0);
|
startCalendar.set(Calendar.SECOND, 0);
|
||||||
startCalendar.set(Calendar.SECOND, 0);
|
startCalendar.set(Calendar.MILLISECOND, 0);
|
||||||
startCalendar.set(Calendar.MILLISECOND, 0);
|
startCalendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||||
startCalendar.set(Calendar.DAY_OF_MONTH, 1);
|
|
||||||
|
Date startDate = startCalendar.getTime();
|
||||||
Date startDate = startCalendar.getTime();
|
|
||||||
|
// Setze die Uhrzeit auf 23:59:59.999
|
||||||
// Setze die Uhrzeit auf 23:59:59.999
|
Calendar endCalendar = Calendar.getInstance();
|
||||||
Calendar endCalendar = Calendar.getInstance();
|
endCalendar.setTime(dueDate);
|
||||||
endCalendar.setTime(dueDate);
|
endCalendar.set(Calendar.HOUR_OF_DAY, 23);
|
||||||
endCalendar.set(Calendar.HOUR_OF_DAY, 23);
|
endCalendar.set(Calendar.MINUTE, 59);
|
||||||
endCalendar.set(Calendar.MINUTE, 59);
|
endCalendar.set(Calendar.SECOND, 59);
|
||||||
endCalendar.set(Calendar.SECOND, 59);
|
endCalendar.set(Calendar.MILLISECOND, 999);
|
||||||
endCalendar.set(Calendar.MILLISECOND, 999);
|
endCalendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||||
endCalendar.set(Calendar.DAY_OF_MONTH, 1);
|
endCalendar.add(Calendar.MONTH, 1);
|
||||||
endCalendar.add(Calendar.MONTH, 1);
|
endCalendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||||
endCalendar.add(Calendar.DAY_OF_MONTH, -1);
|
|
||||||
|
Date endDate = endCalendar.getTime();
|
||||||
Date endDate = endCalendar.getTime();
|
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
||||||
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;
|
||||||
|
}
|
||||||
return dateRange;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -40,7 +40,7 @@ public class DebitorStatistikData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aktualisiert die statistischen werte
|
* Aktualisiert die statistischen werte
|
||||||
*
|
*
|
||||||
* @param invoiceDate
|
* @param invoiceDate
|
||||||
* @param paymentDate
|
* @param paymentDate
|
||||||
*/
|
*/
|
||||||
|
|
@ -90,7 +90,7 @@ public class DebitorStatistikData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns
|
* returns
|
||||||
*
|
*
|
||||||
* 202304
|
* 202304
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -42,7 +42,7 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FTPConnector service provides methods to push invoices to cargosoft
|
* The FTPConnector service provides methods to push invoices to cargosoft
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -83,7 +83,7 @@ public class FTPConnector {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method transfers a snapshot to a ftp server.
|
* This method transfers a snapshot to a ftp server.
|
||||||
*
|
*
|
||||||
* @param fileData object
|
* @param fileData object
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -158,7 +158,7 @@ public class FTPConnector {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method reads data form the current working directory
|
* This method reads data form the current working directory
|
||||||
*
|
*
|
||||||
* @param snapshot
|
* @param snapshot
|
||||||
* @throws ArchiveException
|
* @throws ArchiveException
|
||||||
* @return data
|
* @return data
|
||||||
|
|
@ -198,7 +198,7 @@ public class FTPConnector {
|
||||||
/**
|
/**
|
||||||
* This method changes the current working sub-directy. If no corresponding
|
* This method changes the current working sub-directy. If no corresponding
|
||||||
* directory exits the method creats one.
|
* directory exits the method creats one.
|
||||||
*
|
*
|
||||||
* @throws ArchiveException
|
* @throws ArchiveException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import jakarta.inject.Named;
|
||||||
/**
|
/**
|
||||||
* Der InvoiceAnalyseController dient zur Auswertung der Sachprüfungs Workflow
|
* Der InvoiceAnalyseController dient zur Auswertung der Sachprüfungs Workflow
|
||||||
* Schritte. Die Analyse Seite ist über das Admin Menü erreichbar.
|
* Schritte. Die Analyse Seite ist über das Admin Menü erreichbar.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -30,138 +30,138 @@ import jakarta.inject.Named;
|
||||||
@ConversationScoped
|
@ConversationScoped
|
||||||
public class InvoiceAnalyseController implements Serializable {
|
public class InvoiceAnalyseController implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(InvoiceAnalyseController.class.getName());
|
private static Logger logger = Logger.getLogger(InvoiceAnalyseController.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected DocumentService documentService;
|
protected DocumentService documentService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SearchService searchService;
|
SearchService searchService;
|
||||||
|
|
||||||
Category sachpruefung;
|
Category sachpruefung;
|
||||||
Category verteilung;
|
Category verteilung;
|
||||||
Category buchhaltung;
|
Category buchhaltung;
|
||||||
|
|
||||||
private ItemCollection filter;
|
private ItemCollection filter;
|
||||||
|
|
||||||
public ItemCollection getFilter() {
|
public ItemCollection getFilter() {
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
filter = new ItemCollection();
|
filter = new ItemCollection();
|
||||||
// compute start stop based on current month
|
// compute start stop based on current month
|
||||||
YearMonth startYearMonth = YearMonth.now();
|
YearMonth startYearMonth = YearMonth.now();
|
||||||
java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
|
java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
|
||||||
java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
|
java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
|
||||||
filter.setItemValue("start",
|
filter.setItemValue("start",
|
||||||
java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
filter.setItemValue("stop",
|
filter.setItemValue("stop",
|
||||||
java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
}
|
}
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilter(ItemCollection filter) {
|
public void setFilter(ItemCollection filter) {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Category getSachpruefung() {
|
public Category getSachpruefung() {
|
||||||
return sachpruefung;
|
return sachpruefung;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Category getVerteilung() {
|
public Category getVerteilung() {
|
||||||
return verteilung;
|
return verteilung;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Category getBuchhaltung() {
|
public Category getBuchhaltung() {
|
||||||
return buchhaltung;
|
return buchhaltung;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int totalCountByCategory(Category cat) {
|
public int totalCountByCategory(Category cat) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
Collection<Integer> allCounts = cat.getLabels().values();
|
Collection<Integer> allCounts = cat.getLabels().values();
|
||||||
result = allCounts.stream().reduce(0, Integer::sum);
|
result = allCounts.stream().reduce(0, Integer::sum);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
|
* Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
|
||||||
*/
|
*/
|
||||||
public void analyse() {
|
public void analyse() {
|
||||||
|
|
||||||
logger.info("start analyse....");
|
logger.info("start analyse....");
|
||||||
verteilung = null;
|
verteilung = null;
|
||||||
sachpruefung = null;
|
sachpruefung = null;
|
||||||
Date start = filter.getItemValueDate("start");
|
Date start = filter.getItemValueDate("start");
|
||||||
Date stop = filter.getItemValueDate("stop");
|
Date stop = filter.getItemValueDate("stop");
|
||||||
|
|
||||||
logger.info("...daterange=" + start + " - " + stop);
|
logger.info("...daterange=" + start + " - " + stop);
|
||||||
|
|
||||||
// serach date range?
|
// serach date range?
|
||||||
String sDateFrom = "191401070000"; // because * did not work here
|
String sDateFrom = "191401070000"; // because * did not work here
|
||||||
String sDateTo = "211401070000";
|
String sDateTo = "211401070000";
|
||||||
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
||||||
|
|
||||||
if (start != null) {
|
if (start != null) {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTime(start);
|
cal.setTime(start);
|
||||||
sDateFrom = dateformat.format(cal.getTime());
|
sDateFrom = dateformat.format(cal.getTime());
|
||||||
}
|
}
|
||||||
if (stop != null) {
|
if (stop != null) {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTime(stop);
|
cal.setTime(stop);
|
||||||
cal.add(Calendar.DATE, 1);
|
cal.add(Calendar.DATE, 1);
|
||||||
sDateTo = dateformat.format(cal.getTime());
|
sDateTo = dateformat.format(cal.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
// query Verteilung
|
// query Verteilung
|
||||||
String query = "(type:workitem OR type:workitemarchive) ";
|
String query = "(type:workitem OR type:workitemarchive) ";
|
||||||
if (start != null || stop != null) {
|
if (start != null || stop != null) {
|
||||||
query += "AND (taxonomy.verteilung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
query += "AND (taxonomy.verteilung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
||||||
}
|
}
|
||||||
logger.info(query);
|
logger.info(query);
|
||||||
List<Category> taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.verteilung.stop.by");
|
List<Category> taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.verteilung.stop.by");
|
||||||
if (taxResult.size() > 0) {
|
if (taxResult.size() > 0) {
|
||||||
verteilung = taxResult.get(0);
|
verteilung = taxResult.get(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// query Sachprüfung
|
// query Sachprüfung
|
||||||
query = "(type:workitem OR type:workitemarchive) ";
|
query = "(type:workitem OR type:workitemarchive) ";
|
||||||
if (start != null || stop != null) {
|
if (start != null || stop != null) {
|
||||||
query += "AND (taxonomy.sachpruefung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
query += "AND (taxonomy.sachpruefung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
||||||
}
|
}
|
||||||
logger.info(query);
|
logger.info(query);
|
||||||
taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.sachpruefung.stop.by");
|
taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.sachpruefung.stop.by");
|
||||||
if (taxResult.size() > 0) {
|
if (taxResult.size() > 0) {
|
||||||
sachpruefung = taxResult.get(0);
|
sachpruefung = taxResult.get(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// query Buchhaltung
|
// query Buchhaltung
|
||||||
query = "(type:workitem OR type:workitemarchive) ";
|
query = "(type:workitem OR type:workitemarchive) ";
|
||||||
if (start != null || stop != null) {
|
if (start != null || stop != null) {
|
||||||
query += "AND (taxonomy.buchhaltung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
query += "AND (taxonomy.buchhaltung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
||||||
}
|
}
|
||||||
logger.info(query);
|
logger.info(query);
|
||||||
taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.buchhaltung.stop.by");
|
taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.buchhaltung.stop.by");
|
||||||
if (taxResult.size() > 0) {
|
if (taxResult.size() > 0) {
|
||||||
buchhaltung = taxResult.get(0);
|
buchhaltung = taxResult.get(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method reset the search and input state.
|
* This method reset the search and input state.
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
filter = new ItemCollection();
|
filter = new ItemCollection();
|
||||||
sachpruefung = null;
|
sachpruefung = null;
|
||||||
verteilung = null;
|
verteilung = null;
|
||||||
buchhaltung = null;
|
buchhaltung = null;
|
||||||
logger.fine("reset");
|
logger.fine("reset");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import jakarta.inject.Inject;
|
||||||
/**
|
/**
|
||||||
* Der InvoiceDispatchAdapter verteilt die vom Abteilungsleiter ausgewählten
|
* Der InvoiceDispatchAdapter verteilt die vom Abteilungsleiter ausgewählten
|
||||||
* Rechnungen
|
* Rechnungen
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -29,7 +29,7 @@ public class InvoiceDispatchAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method computes the cargosoft export data file
|
* This method computes the cargosoft export data file
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The InvoiceDispatchController loads open workitems for the current user
|
* The InvoiceDispatchController loads open workitems for the current user
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -50,7 +50,7 @@ public class InvoiceDispatchController implements Serializable {
|
||||||
* ($modelversion:rechnungseingang-de*) AND ($taskid:5100) AND
|
* ($modelversion:rechnungseingang-de*) AND ($taskid:5100) AND
|
||||||
* ($owner:#{user})"></ui:param> <ui:param name="invoiceList" value=
|
* ($owner:#{user})"></ui:param> <ui:param name="invoiceList" value=
|
||||||
* "#{workflowController.documentService.find(query,30,0)}"></ui:param>
|
* "#{workflowController.documentService.find(query,30,0)}"></ui:param>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void searchInvoices() {
|
public void searchInvoices() {
|
||||||
long l = System.currentTimeMillis();
|
long l = System.currentTimeMillis();
|
||||||
|
|
|
||||||
|
|
@ -8,40 +8,40 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Das InvoiceOutgoingPlugin aktualisiert die Debitor E-Mail Adresse
|
* Das InvoiceOutgoingPlugin aktualisiert die Debitor E-Mail Adresse
|
||||||
*
|
*
|
||||||
* Auch das feld _img wird in Abhängigkeit vom item 'invoice.protest' gesetzt
|
* Auch das feld _img wird in Abhängigkeit vom item 'invoice.protest' gesetzt
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InvoiceOutgoingPlugin extends AbstractPlugin {
|
public class InvoiceOutgoingPlugin extends AbstractPlugin {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BusinessPartnerService businessPartnerService;
|
BusinessPartnerService businessPartnerService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @throws PluginException - if data is missing
|
* @throws PluginException - if data is missing
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
||||||
|
|
||||||
// Update BUsiness Partner Data
|
// Update BUsiness Partner Data
|
||||||
businessPartnerService.updateBusinessPartnerData(workitem);
|
businessPartnerService.updateBusinessPartnerData(workitem);
|
||||||
|
|
||||||
// Update Invoice.positions
|
// Update Invoice.positions
|
||||||
InvoiceUtil.updateInvoicePositions(workitem);
|
InvoiceUtil.updateInvoicePositions(workitem);
|
||||||
|
|
||||||
String img = "";
|
String img = "";
|
||||||
if (workitem.getItemValueBoolean("invoice.protest")) {
|
if (workitem.getItemValueBoolean("invoice.protest")) {
|
||||||
img = img + "<img title='Reklamiert' src=\"/layout/icons/icon106.png\">";
|
img = img + "<img title='Reklamiert' src=\"/layout/icons/icon106.png\">";
|
||||||
|
|
||||||
}
|
}
|
||||||
workitem.setItemValue("_img", img);
|
workitem.setItemValue("_img", img);
|
||||||
|
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,403 +35,402 @@ import jakarta.inject.Inject;
|
||||||
* <p>
|
* <p>
|
||||||
* 2.2.22 - Das Plugin erzeugt auch das Feld _img welches die Images von
|
* 2.2.22 - Das Plugin erzeugt auch das Feld _img welches die Images von
|
||||||
* Sofortüberweisung, Mahnung und Ablehnung anzeigt.
|
* Sofortüberweisung, Mahnung und Ablehnung anzeigt.
|
||||||
*
|
*
|
||||||
* 26.4.25 - Das Plugin setzt nun auch partner.name und partner.id
|
* 26.4.25 - Das Plugin setzt nun auch partner.name und partner.id zusätzlich
|
||||||
* zusätzlich processed es das BP Workitem
|
* processed es das BP Workitem
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InvoicePlugin extends AbstractPlugin {
|
public class InvoicePlugin extends AbstractPlugin {
|
||||||
|
|
||||||
public static final int TASK_ERFASSUNG = 5001;
|
public static final int TASK_ERFASSUNG = 5001;
|
||||||
public static final int TASK_SACHPRUEFUNG = 5200;
|
public static final int TASK_SACHPRUEFUNG = 5200;
|
||||||
public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210;
|
public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210;
|
||||||
public static final int EVENT_FREIGEBEN = 20;
|
public static final int EVENT_FREIGEBEN = 20;
|
||||||
|
|
||||||
public static final String ERROR_MISSING_DATA = "MISSING_DATA";
|
public static final String ERROR_MISSING_DATA = "MISSING_DATA";
|
||||||
public static final String ERROR_DUPPLICATE_INVOICE_NUMBER = "DUPPLICATE_INVOICE_NUMBER";
|
public static final String ERROR_DUPPLICATE_INVOICE_NUMBER = "DUPPLICATE_INVOICE_NUMBER";
|
||||||
public static final String ERROR_NEW_IBANBIC = "NEW_IBANBIC";
|
public static final String ERROR_NEW_IBANBIC = "NEW_IBANBIC";
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(InvoicePlugin.class.getName());
|
private static Logger logger = Logger.getLogger(InvoicePlugin.class.getName());
|
||||||
|
|
||||||
// Positions Pattern - kann überschrieben werden
|
// Positions Pattern - kann überschrieben werden
|
||||||
// XX-YYY-####-### oder XX-YYYZZZ-####-###
|
// XX-YYY-####-### oder XX-YYYZZZ-####-###
|
||||||
// Default = ([A-Z]{2}-[A-Z]{3}-[0-9]{4}-[0-9]{3})
|
// Default = ([A-Z]{2}-[A-Z]{3}-[0-9]{4}-[0-9]{3})
|
||||||
// Optional = ([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})
|
// Optional = ([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})
|
||||||
// Nur 6- Stellig = ([A-Z]{2}-(?:[A-Z]{6})-[0-9]{4}-[0-9]{3})
|
// Nur 6- Stellig = ([A-Z]{2}-(?:[A-Z]{6})-[0-9]{4}-[0-9]{3})
|
||||||
public final static String INVOICE_POSITIONS_PATTERN_DEFAULT = "([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})";
|
public final static String INVOICE_POSITIONS_PATTERN_DEFAULT = "([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ConfigProperty(name = "invoice.position.pattern", defaultValue = INVOICE_POSITIONS_PATTERN_DEFAULT)
|
@ConfigProperty(name = "invoice.position.pattern", defaultValue = INVOICE_POSITIONS_PATTERN_DEFAULT)
|
||||||
String invoicePositionsPattern;
|
String invoicePositionsPattern;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BusinessPartnerService businessPartnerService;
|
BusinessPartnerService businessPartnerService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ResourceBundleHandler resourceBundleHandler;
|
ResourceBundleHandler resourceBundleHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test childworkitems for empty lines
|
* Test childworkitems for empty lines
|
||||||
*
|
*
|
||||||
* @throws PluginException - if data is missing
|
* @throws PluginException - if data is missing
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
||||||
|
|
||||||
// Update BUsiness Partner Data
|
// Update BUsiness Partner Data
|
||||||
businessPartnerService.updateBusinessPartnerData(workitem);
|
businessPartnerService.updateBusinessPartnerData(workitem);
|
||||||
|
|
||||||
updateImg(workitem);
|
updateImg(workitem);
|
||||||
|
|
||||||
// Update Invoice.positions
|
// Update Invoice.positions
|
||||||
InvoiceUtil.updateInvoicePositions(workitem);
|
InvoiceUtil.updateInvoicePositions(workitem);
|
||||||
|
|
||||||
// skip if validaten tag is required=false
|
// skip if validaten tag is required=false
|
||||||
ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem);
|
ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem);
|
||||||
if (evalItemCollection != null) {
|
if (evalItemCollection != null) {
|
||||||
// evaluate the validation rules...
|
// evaluate the validation rules...
|
||||||
if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) {
|
if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) {
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult")));
|
boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult")));
|
||||||
|
|
||||||
// Payment.type muss immer eingetragne werden!
|
// Payment.type muss immer eingetragne werden!
|
||||||
if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) {
|
if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) {
|
||||||
if (workitem.getItemValueString("payment.type").trim().isEmpty()) {
|
if (workitem.getItemValueString("payment.type").trim().isEmpty()) {
|
||||||
// throw a plugin exception!
|
// throw a plugin exception!
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_MISSING_PAYMENT");
|
String message = resourceBundleHandler.findMessage("ERROR_MISSING_PAYMENT");
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
}
|
}
|
||||||
// doppelte Rechnungsnummer prüfen
|
// doppelte Rechnungsnummer prüfen
|
||||||
if (workitem.getTaskID() == TASK_ERFASSUNG) {
|
if (workitem.getTaskID() == TASK_ERFASSUNG) {
|
||||||
validateInvoiceNumber(workitem);
|
validateInvoiceNumber(workitem);
|
||||||
checkIBANNumber(workitem);
|
checkIBANNumber(workitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG
|
if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG
|
||||||
|| workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
|| workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
||||||
&& workitem.getEventID() == EVENT_FREIGEBEN)) {
|
&& workitem.getEventID() == EVENT_FREIGEBEN)) {
|
||||||
// Buchungsperiode auf plausi prüfen
|
// Buchungsperiode auf plausi prüfen
|
||||||
if (isCargoRechnung(workitem) && "workitem".equals(workitem.getType())) {
|
if (isCargoRechnung(workitem) && "workitem".equals(workitem.getType())) {
|
||||||
validateBuchungsperiode(workitem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
|
validateBuchungsperiode(workitem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
|
||||||
}
|
}
|
||||||
// Cargosoft Kreditorennnummer prüfen
|
// Cargosoft Kreditorennnummer prüfen
|
||||||
if (isCargoRechnung(workitem)) {
|
if (isCargoRechnung(workitem)) {
|
||||||
validateCargosoftCdtrNumber(workitem);
|
validateCargosoftCdtrNumber(workitem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// die prüfung der positionsnummern und Category erfolgt nur im Status
|
// die prüfung der positionsnummern und Category erfolgt nur im Status
|
||||||
// Sachprüfung (5200) und nur beim Freigeben (20)!
|
// Sachprüfung (5200) und nur beim Freigeben (20)!
|
||||||
if (isCargoRechnung(workitem)
|
if (isCargoRechnung(workitem)
|
||||||
&& ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
&& ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
|
||||||
&& workitem.getEventID() == EVENT_FREIGEBEN)) {
|
&& workitem.getEventID() == EVENT_FREIGEBEN)) {
|
||||||
List<ItemCollection> childs = InvoiceUtil.explodeChildList(workitem);
|
List<ItemCollection> childs = InvoiceUtil.explodeChildList(workitem);
|
||||||
for (ItemCollection posItem : childs) {
|
for (ItemCollection posItem : childs) {
|
||||||
if (posItem.getItemValueString("name").trim().isEmpty()) {
|
if (posItem.getItemValueString("name").trim().isEmpty()) {
|
||||||
// throw a plugin exception - because name is missing!
|
// throw a plugin exception - because name is missing!
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_MISSING_POSNO");
|
String message = resourceBundleHandler.findMessage("ERROR_MISSING_POSNO");
|
||||||
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate pos for regex pattern 'XX-YYY-####-###'
|
// validate pos for regex pattern 'XX-YYY-####-###'
|
||||||
if (!posItem.getItemValueString("name").matches(invoicePositionsPattern)) {
|
if (!posItem.getItemValueString("name").matches(invoicePositionsPattern)) {
|
||||||
// throw a plugin exception - because name is missing!
|
// throw a plugin exception - because name is missing!
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_FORMAT_POSNO");
|
String message = resourceBundleHandler.findMessage("ERROR_FORMAT_POSNO");
|
||||||
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (posItem.getItemValueString("category").trim().isEmpty()) {
|
if (posItem.getItemValueString("category").trim().isEmpty()) {
|
||||||
// throw a plugin exception - because name is missing!
|
// throw a plugin exception - because name is missing!
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_MISSING_CATEGORY");
|
String message = resourceBundleHandler.findMessage("ERROR_MISSING_CATEGORY");
|
||||||
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
|
||||||
"Eingabefehler - Die Leistungsart in Zeile " + posItem.getItemValueString("numpos")
|
"Eingabefehler - Die Leistungsart in Zeile " + posItem.getItemValueString("numpos")
|
||||||
+ " muss ausgefüllt sein!");
|
+ " muss ausgefüllt sein!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (posItem.getItemValueString("tax").trim().isEmpty()) {
|
if (posItem.getItemValueString("tax").trim().isEmpty()) {
|
||||||
// throw a plugin exception - because name is missing!
|
// throw a plugin exception - because name is missing!
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_MISSING_TAX");
|
String message = resourceBundleHandler.findMessage("ERROR_MISSING_TAX");
|
||||||
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (posItem.getItemValueFloat("amount") == 0) {
|
if (posItem.getItemValueFloat("amount") == 0) {
|
||||||
// throw a plugin exception - because name is missing!
|
// throw a plugin exception - because name is missing!
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_MISSING_NET");
|
String message = resourceBundleHandler.findMessage("ERROR_MISSING_NET");
|
||||||
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
message = message.replace("{1}", posItem.getItemValueString("numpos"));
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buchunsperiode
|
// Buchunsperiode
|
||||||
if (!posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD).trim().isEmpty()) {
|
if (!posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD).trim().isEmpty()) {
|
||||||
validateBuchungsperiode(posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
|
validateBuchungsperiode(posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ergaenzung 18.05.2021:
|
// Ergaenzung 18.05.2021:
|
||||||
// es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so
|
// es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so
|
||||||
// das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der
|
// das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der
|
||||||
// fall sein.
|
// fall sein.
|
||||||
// Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder
|
// Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder
|
||||||
// die Hauptbuchunsperiode ausgewählt wurde. Ist das nicht der Fal gibt es eine
|
// die Hauptbuchunsperiode ausgewählt wurde. Ist das nicht der Fal gibt es eine
|
||||||
// Fehlermeldung für den Anwendere
|
// Fehlermeldung für den Anwendere
|
||||||
if (isCargoRechnung(workitem) && childs.size() > 0) {
|
if (isCargoRechnung(workitem) && childs.size() > 0) {
|
||||||
String hauptBuchungsperiode = workitem.getItemValueString("invoice.period");
|
String hauptBuchungsperiode = workitem.getItemValueString("invoice.period");
|
||||||
boolean buchungsperiodenValid = false;
|
boolean buchungsperiodenValid = false;
|
||||||
for (ItemCollection posItem : childs) {
|
for (ItemCollection posItem : childs) {
|
||||||
String posBuchungsperiode = posItem.getItemValueString("invoice.period");
|
String posBuchungsperiode = posItem.getItemValueString("invoice.period");
|
||||||
if (posBuchungsperiode.isEmpty() || posBuchungsperiode.equals(hauptBuchungsperiode)) {
|
if (posBuchungsperiode.isEmpty() || posBuchungsperiode.equals(hauptBuchungsperiode)) {
|
||||||
// alles fein!
|
// alles fein!
|
||||||
buchungsperiodenValid = true;
|
buchungsperiodenValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buchungsperiodenValid == false) {
|
if (buchungsperiodenValid == false) {
|
||||||
// fehlerhafte Buchungsperioden.
|
// fehlerhafte Buchungsperioden.
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_MAIN_BOOKING_PERIOD");
|
String message = resourceBundleHandler.findMessage("ERROR_MAIN_BOOKING_PERIOD");
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsroutine die das _img item aktualisiert.
|
* Hilfsroutine die das _img item aktualisiert.
|
||||||
*/
|
*/
|
||||||
private void updateImg(ItemCollection workitem) {
|
private void updateImg(ItemCollection workitem) {
|
||||||
|
|
||||||
// Update _img icon list
|
// Update _img icon list
|
||||||
String img = workitem.getItemValueString("_img");
|
String img = workitem.getItemValueString("_img");
|
||||||
// 031=ablehnen
|
// 031=ablehnen
|
||||||
// 100=sofortüberweichung
|
// 100=sofortüberweichung
|
||||||
// 074=mahnen
|
// 074=mahnen
|
||||||
// sofortüberweisung
|
// sofortüberweisung
|
||||||
if (workitem.getEventID() == 96 && !img.contains("100.png")) {
|
if (workitem.getEventID() == 96 && !img.contains("100.png")) {
|
||||||
img = img + "<img title='Sofortüberweisung' src=\"/layout/icons/icon100.png\">";
|
img = img + "<img title='Sofortüberweisung' src=\"/layout/icons/icon100.png\">";
|
||||||
}
|
}
|
||||||
// mahnen
|
// mahnen
|
||||||
if (workitem.getEventID() == 95 && !img.contains("103.png")) {
|
if (workitem.getEventID() == 95 && !img.contains("103.png")) {
|
||||||
img = img + "<img title='Mahnen' src=\"/layout/icons/icon103.png\">";
|
img = img + "<img title='Mahnen' src=\"/layout/icons/icon103.png\">";
|
||||||
|
|
||||||
}
|
}
|
||||||
// ablehnen
|
// ablehnen
|
||||||
if (workitem.getTaskID() == 5100 && workitem.getEventID() == 90 && !img.contains("028.png")) {
|
if (workitem.getTaskID() == 5100 && workitem.getEventID() == 90 && !img.contains("028.png")) {
|
||||||
img = img + "<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
|
img = img + "<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
|
||||||
}
|
}
|
||||||
if (workitem.getTaskID() == 5200 && workitem.getEventID() == 90 && !img.contains("028.png")) {
|
if (workitem.getTaskID() == 5200 && workitem.getEventID() == 90 && !img.contains("028.png")) {
|
||||||
img = img + "<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
|
img = img + "<img title='Abgelehnt' src=\"/layout/icons/icon028.png\">";
|
||||||
}
|
}
|
||||||
workitem.setItemValue("_img", img);
|
workitem.setItemValue("_img", img);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Method prüft die Buchungsperiode auf Plausibilität
|
* Diese Method prüft die Buchungsperiode auf Plausibilität
|
||||||
*
|
*
|
||||||
* YYYY(+1)01-12
|
* YYYY(+1)01-12
|
||||||
*
|
*
|
||||||
* z.b. 202110 oder 202107 oder 202201
|
* z.b. 202110 oder 202107 oder 202201
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private void validateBuchungsperiode(String period) throws PluginException {
|
private void validateBuchungsperiode(String period) throws PluginException {
|
||||||
|
|
||||||
// buchungsperionde nur prüfen wenn noch nicht archiviert
|
// buchungsperionde nur prüfen wenn noch nicht archiviert
|
||||||
if (!period.isEmpty()) {
|
if (!period.isEmpty()) {
|
||||||
LocalDate localDate = LocalDate.now();
|
LocalDate localDate = LocalDate.now();
|
||||||
int year = localDate.getYear();
|
int year = localDate.getYear();
|
||||||
// build regex....
|
// build regex....
|
||||||
String regex = "(" + year + "|" + (year + 1) + "|" + (year - 1) + ")(1[0-2]|0[1-9])";
|
String regex = "(" + year + "|" + (year + 1) + "|" + (year - 1) + ")(1[0-2]|0[1-9])";
|
||||||
|
|
||||||
if (!period.matches(regex)) {
|
if (!period.matches(regex)) {
|
||||||
// throw a plugin exception - because name is missing!
|
// throw a plugin exception - because name is missing!
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_BOOKING_PERIOD");
|
String message = resourceBundleHandler.findMessage("ERROR_BOOKING_PERIOD");
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Method prüft ob die "invoice.number" bereits einmal im
|
* Diese Method prüft ob die "invoice.number" bereits einmal im
|
||||||
* Rechnugnsworkflow vergeben wurde. Falls ja wird eine PluginExcpetion
|
* Rechnugnsworkflow vergeben wurde. Falls ja wird eine PluginExcpetion
|
||||||
* ausgelöst.
|
* ausgelöst.
|
||||||
* <p>
|
* <p>
|
||||||
* Query Example:
|
* Query Example:
|
||||||
* <p>
|
* <p>
|
||||||
* <code>NOT $uniqueid:"9f72fa50-4845-41ea-b6b9-ccd518c353be" AND
|
* <code>NOT $uniqueid:"9f72fa50-4845-41ea-b6b9-ccd518c353be" AND
|
||||||
txtcooperatespace:"9dba107e-f8ef-4150-a832-040d75a6eda7" AND invoice.number:"45"</code>
|
txtcooperatespace:"9dba107e-f8ef-4150-a832-040d75a6eda7" AND invoice.number:"45"</code>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* in case a duplicate invoice was detected the item invoice.number.duplicate is
|
* in case a duplicate invoice was detected the item invoice.number.duplicate is
|
||||||
* filled. This item is used for a conditional event. The case is displayed as a
|
* filled. This item is used for a conditional event. The case is displayed as a
|
||||||
* warning in the form.
|
* warning in the form.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void validateInvoiceNumber(ItemCollection workitem) throws PluginException {
|
private void validateInvoiceNumber(ItemCollection workitem) throws PluginException {
|
||||||
|
|
||||||
String invoiceNumber = workitem.getItemValueString("invoice.number");
|
String invoiceNumber = workitem.getItemValueString("invoice.number");
|
||||||
// strip
|
// strip
|
||||||
String invoiceNumberStripped = invoiceNumber.replace(" ", "");
|
String invoiceNumberStripped = invoiceNumber.replace(" ", "");
|
||||||
workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped);
|
workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped);
|
||||||
String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
|
String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
|
||||||
|
|
||||||
// wenn keine Rechnungsnummer eingegeben wurde gehts weiter!
|
// wenn keine Rechnungsnummer eingegeben wurde gehts weiter!
|
||||||
if (invoiceNumber.isEmpty()) {
|
if (invoiceNumber.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rechnungseingang only workitems...
|
// rechnungseingang only workitems...
|
||||||
// Change 11.4.22 - we have now an additional field: invoice.number.stripped
|
// Change 11.4.22 - we have now an additional field: invoice.number.stripped
|
||||||
String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\""
|
String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\""
|
||||||
+ workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped
|
+ workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped
|
||||||
+ "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))";
|
+ "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))";
|
||||||
try {
|
try {
|
||||||
int result = this.getWorkflowService().getDocumentService().count(query, 1);
|
int result = this.getWorkflowService().getDocumentService().count(query, 1);
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
// wenn _invoicenumber_duplicate bereits gesetzt ist - dann geht es ohne prüfung
|
// wenn _invoicenumber_duplicate bereits gesetzt ist - dann geht es ohne prüfung
|
||||||
// weiter
|
// weiter
|
||||||
if (!invoiceNumberDuplicate.isEmpty()) {
|
if (!invoiceNumberDuplicate.isEmpty()) {
|
||||||
logger.warning("...validateion skipped by user with duplicate invoice number: " + invoiceNumber);
|
logger.warning("...validateion skipped by user with duplicate invoice number: " + invoiceNumber);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// set _invoicenumber_duplicate - dadurch wird die warnmeldung ausgegeben und
|
// set _invoicenumber_duplicate - dadurch wird die warnmeldung ausgegeben und
|
||||||
// der Vorgang nicht weitergeleitet
|
// der Vorgang nicht weitergeleitet
|
||||||
workitem.replaceItemValue("invoice.number.duplicate", invoiceNumber);
|
workitem.replaceItemValue("invoice.number.duplicate", invoiceNumber);
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_INVOICENO");
|
String message = resourceBundleHandler.findMessage("ERROR_INVOICENO");
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_DUPPLICATE_INVOICE_NUMBER, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_DUPPLICATE_INVOICE_NUMBER, message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// clear !
|
// clear !
|
||||||
workitem.appendItemValue("invoice.number.duplicate.history",
|
workitem.appendItemValue("invoice.number.duplicate.history",
|
||||||
workitem.getItemValueString("invoice.number.duplicate"));
|
workitem.getItemValueString("invoice.number.duplicate"));
|
||||||
workitem.replaceItemValue("invoice.number.duplicate", "");
|
workitem.replaceItemValue("invoice.number.duplicate", "");
|
||||||
}
|
}
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
throw new PluginException(PluginException.class.getName(), "QUERY ERROR", e.getMessage(), e);
|
throw new PluginException(PluginException.class.getName(), "QUERY ERROR", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Method prüft ob die eingegebene IBAN nummer bereits in dem ausgewälten
|
* Diese Method prüft ob die eingegebene IBAN nummer bereits in dem ausgewälten
|
||||||
* Kreditor bekannt ist. Fallst nicht wird diese schnell mal in den Kreditoren
|
* Kreditor bekannt ist. Fallst nicht wird diese schnell mal in den Kreditoren
|
||||||
* Datensatz übertragen. Dadurch muss man nicht extra die Kreditoren Verwaltung
|
* Datensatz übertragen. Dadurch muss man nicht extra die Kreditoren Verwaltung
|
||||||
* aufrufen. Es ist ein art selbst-lernendes System.
|
* aufrufen. Es ist ein art selbst-lernendes System.
|
||||||
* <p>
|
* <p>
|
||||||
* Die Mehtode ruft eine Plugin Exception aus um den User zu fragen ob er das
|
* Die Mehtode ruft eine Plugin Exception aus um den User zu fragen ob er das
|
||||||
* möchte.
|
* möchte.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void checkIBANNumber(ItemCollection workitem) throws PluginException {
|
private void checkIBANNumber(ItemCollection workitem) throws PluginException {
|
||||||
|
|
||||||
String cdtrNumber = workitem.getItemValueString("cdtr.number");
|
String cdtrNumber = workitem.getItemValueString("cdtr.number");
|
||||||
String iban = workitem.getItemValueString("cdtr.iban");
|
String iban = workitem.getItemValueString("cdtr.iban");
|
||||||
String bic = workitem.getItemValueString("cdtr.bic");
|
String bic = workitem.getItemValueString("cdtr.bic");
|
||||||
String overtakeIBAN = workitem.getItemValueString("ibanbic.overtake");
|
String overtakeIBAN = workitem.getItemValueString("ibanbic.overtake");
|
||||||
|
|
||||||
if (cdtrNumber.isEmpty() || iban.isEmpty() || bic.isEmpty()) {
|
if (cdtrNumber.isEmpty() || iban.isEmpty() || bic.isEmpty()) {
|
||||||
// no op
|
// no op
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemCollection businessPartner = businessPartnerService
|
ItemCollection businessPartner = businessPartnerService
|
||||||
.getBusinessPartnerByID(InvoiceUtil.buildBPID(cdtrNumber));
|
.getBusinessPartnerByID(InvoiceUtil.buildBPID(cdtrNumber));
|
||||||
if (businessPartner != null) {
|
if (businessPartner != null) {
|
||||||
// update country
|
// update country
|
||||||
workitem.setItemValue("invoice.country", businessPartner.getItemValueString("partner.country"));
|
workitem.setItemValue("invoice.country", businessPartner.getItemValueString("partner.country"));
|
||||||
|
|
||||||
// wenn bereits eine Übernahme angedroht wurde, dann übernehmen wir die neue
|
// wenn bereits eine Übernahme angedroht wurde, dann übernehmen wir die neue
|
||||||
// IBAN/BIC!
|
// IBAN/BIC!
|
||||||
if (!overtakeIBAN.isEmpty()) {
|
if (!overtakeIBAN.isEmpty()) {
|
||||||
businessPartnerService.addNewIBANBIC(businessPartner, iban, bic);
|
businessPartnerService.addNewIBANBIC(businessPartner, iban, bic);
|
||||||
workitem.setItemValue("ibanbic.overtake", "");
|
workitem.setItemValue("ibanbic.overtake", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prüfen ob wir die IBAN schon kennen
|
// Prüfen ob wir die IBAN schon kennen
|
||||||
if (!businessPartnerService.isIBANBICKnown(businessPartner, iban, bic)) {
|
if (!businessPartnerService.isIBANBICKnown(businessPartner, iban, bic)) {
|
||||||
// OK - scheinbar ist diese IBAN/BIC nicht bekannt. Also fragen wir mal nach....
|
// OK - scheinbar ist diese IBAN/BIC nicht bekannt. Also fragen wir mal nach....
|
||||||
workitem.setItemValue("ibanbic.overtake", iban + bic);
|
workitem.setItemValue("ibanbic.overtake", iban + bic);
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_IBAN_UNKNOWN");
|
String message = resourceBundleHandler.findMessage("ERROR_IBAN_UNKNOWN");
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_NEW_IBANBIC, message);
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_NEW_IBANBIC, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethod prüft ob die cdtr.nummer mit einer nummer aus der Cargosoft
|
* Hilfsmethod prüft ob die cdtr.nummer mit einer nummer aus der Cargosoft
|
||||||
* Import Datei übereinstimmt.
|
* Import Datei übereinstimmt.
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private void validateCargosoftCdtrNumber(ItemCollection workitem) throws PluginException {
|
private void validateCargosoftCdtrNumber(ItemCollection workitem) throws PluginException {
|
||||||
String crdtrNumber = workitem.getItemValueString("cdtr.number");
|
String crdtrNumber = workitem.getItemValueString("cdtr.number");
|
||||||
|
|
||||||
// wenn keine Nummer eingegeben wurde gehts weiter!
|
// wenn keine Nummer eingegeben wurde gehts weiter!
|
||||||
if (crdtrNumber.isEmpty()) {
|
if (crdtrNumber.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// search creditor number in cargosoft...
|
// search creditor number in cargosoft...
|
||||||
// die cargosoft Kreditornummer beginnt seltsamerweise mit einem K.....
|
// die cargosoft Kreditornummer beginnt seltsamerweise mit einem K.....
|
||||||
try {
|
try {
|
||||||
String query = "(type:cargosoftkreditor) AND (name:K" + crdtrNumber + " OR name:" + crdtrNumber + ")";
|
String query = "(type:cargosoftkreditor) AND (name:K" + crdtrNumber + " OR name:" + crdtrNumber + ")";
|
||||||
List<ItemCollection> result = this.getWorkflowService().getDocumentService().find(query, 1, 0);
|
List<ItemCollection> result = this.getWorkflowService().getDocumentService().find(query, 1, 0);
|
||||||
if (result == null || result.size() == 0) {
|
if (result == null || result.size() == 0) {
|
||||||
|
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_CDTR_INVALID");
|
String message = resourceBundleHandler.findMessage("ERROR_CDTR_INVALID");
|
||||||
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
|
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
|
||||||
message);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// update cargosoft crediotr name
|
// update cargosoft crediotr name
|
||||||
ItemCollection cargo = result.get(0);
|
ItemCollection cargo = result.get(0);
|
||||||
workitem.setItemValue("cdtr.name.cargosoft", cargo.getItemValueString("_VENDOR_Name"));
|
workitem.setItemValue("cdtr.name.cargosoft", cargo.getItemValueString("_VENDOR_Name"));
|
||||||
}
|
}
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns true if the current workitem is a Cargosoft Invoice.
|
* This method returns true if the current workitem is a Cargosoft Invoice.
|
||||||
*
|
*
|
||||||
* This can be based on different model versions e.g. rechnungseingang-de-1.2,
|
* This can be based on different model versions e.g. rechnungseingang-de-1.2,
|
||||||
* rechnungseingang-pl-1.0, rechnungseingang-dwc-1.0, ...
|
* rechnungseingang-pl-1.0, rechnungseingang-dwc-1.0, ...
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isCargoRechnung(ItemCollection workitem) {
|
public static boolean isCargoRechnung(ItemCollection workitem) {
|
||||||
String REGEX_PATTERN = "rechnungseingang-([a-z]{2}|[a-z]{3})-\\d.\\d";
|
String REGEX_PATTERN = "rechnungseingang-([a-z]{2}|[a-z]{3})-\\d.\\d";
|
||||||
// Erstellen Sie ein Pattern-Objekt
|
// Erstellen Sie ein Pattern-Objekt
|
||||||
Pattern pattern = Pattern.compile(REGEX_PATTERN);
|
Pattern pattern = Pattern.compile(REGEX_PATTERN);
|
||||||
Matcher matcher = pattern.matcher(workitem.getModelVersion());
|
Matcher matcher = pattern.matcher(workitem.getModelVersion());
|
||||||
// Überprüfen, ob das Muster übereinstimmt
|
// Überprüfen, ob das Muster übereinstimmt
|
||||||
return matcher.matches();
|
return matcher.matches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow
|
* Imixs Workflow
|
||||||
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* http://www.imixs.org
|
* http://www.imixs.org
|
||||||
* http://java.net/projects/imixs-workflow
|
* http://java.net/projects/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -47,9 +47,9 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der InvoiceService stellt einige Hilfsmethoden bereit.
|
* Der InvoiceService stellt einige Hilfsmethoden bereit.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
||||||
|
|
@ -79,7 +79,7 @@ public class InvoiceService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liefert die Liste der Ausgehenden Währungen
|
* Liefert die Liste der Ausgehenden Währungen
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -89,8 +89,7 @@ public class InvoiceService {
|
||||||
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
||||||
List<String> currencyList = configItemCollection.getItemValue("currency.out");
|
List<String> currencyList = configItemCollection.getItemValue("currency.out");
|
||||||
if (currencyList == null || currencyList.size() < 1) {
|
if (currencyList == null || currencyList.size() < 1) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"missing Currency configuration - please check parameters");
|
"missing Currency configuration - please check parameters");
|
||||||
}
|
}
|
||||||
return currencyList;
|
return currencyList;
|
||||||
|
|
@ -98,7 +97,7 @@ public class InvoiceService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt die Hauptwährung zurück (1. in der liste)
|
* Gibt die Hauptwährung zurück (1. in der liste)
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -108,8 +107,7 @@ public class InvoiceService {
|
||||||
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
||||||
List<String> currencyList = configItemCollection.getItemValue("currency.out");
|
List<String> currencyList = configItemCollection.getItemValue("currency.out");
|
||||||
if (currencyList == null || currencyList.size() < 1) {
|
if (currencyList == null || currencyList.size() < 1) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"missing Currency configuration - please check parameters");
|
"missing Currency configuration - please check parameters");
|
||||||
}
|
}
|
||||||
return currencyList.get(0);
|
return currencyList.get(0);
|
||||||
|
|
@ -117,7 +115,7 @@ public class InvoiceService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liefert die Liste der Eingehenden Währungen
|
* Liefert die Liste der Eingehenden Währungen
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -127,16 +125,14 @@ public class InvoiceService {
|
||||||
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
|
||||||
List<String> currencyList = configItemCollection.getItemValue("currency.in");
|
List<String> currencyList = configItemCollection.getItemValue("currency.in");
|
||||||
if (currencyList == null || currencyList.size() < 1) {
|
if (currencyList == null || currencyList.size() < 1) {
|
||||||
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"missing Currency configuration - please check parameters");
|
"missing Currency configuration - please check parameters");
|
||||||
}
|
}
|
||||||
return currencyList;
|
return currencyList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft ob der Vorgang überflällig ist.
|
* Prüft ob der Vorgang überflällig ist. Default ist 21 tage.
|
||||||
* Default ist 21 tage.
|
|
||||||
*/
|
*/
|
||||||
public boolean isOverdue(Date date, int taskid) {
|
public boolean isOverdue(Date date, int taskid) {
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
|
|
@ -149,9 +145,9 @@ public class InvoiceService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a text-block ItemCollection for a specified name.
|
* This method returns a text-block ItemCollection for a specified name.
|
||||||
*
|
*
|
||||||
* @param name in attribute txtname
|
* @param name in attribute txtname
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public FileData loadTextBlockFileData(String name, String fileName) {
|
public FileData loadTextBlockFileData(String name, String fileName) {
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,12 @@ import org.imixs.workflow.ItemCollection;
|
||||||
/**
|
/**
|
||||||
* Hilfsmethoden für die Berechnung und Validierung von Ein und
|
* Hilfsmethoden für die Berechnung und Validierung von Ein und
|
||||||
* Ausgangsrechnugnen
|
* Ausgangsrechnugnen
|
||||||
*
|
*
|
||||||
* - Rundungs Methode
|
* - Rundungs Methode - Berechnung der Positionsnummern - Explode Childitems
|
||||||
* - Berechnung der Positionsnummern
|
*
|
||||||
* - Explode Childitems
|
|
||||||
*
|
|
||||||
* See:
|
* See:
|
||||||
* https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places
|
* https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -42,7 +40,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rounds a Flat Value
|
* Rounds a Flat Value
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -54,7 +52,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode zum validieren der Mailadresse
|
* Hilfsmethode zum validieren der Mailadresse
|
||||||
*
|
*
|
||||||
* @param emailAddress
|
* @param emailAddress
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -63,9 +61,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
String regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"
|
String regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"
|
||||||
+ "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
|
+ "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
|
||||||
return Pattern.compile(regexPattern)
|
return Pattern.compile(regexPattern).matcher(emailAddress).matches();
|
||||||
.matcher(emailAddress)
|
|
||||||
.matches();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Deprecated
|
// @Deprecated
|
||||||
|
|
@ -102,7 +98,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the List of ItemCollections back into a List of Map elements
|
* Convert the List of ItemCollections back into a List of Map elements
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
public static void implodeChildList(ItemCollection workitem, List<ItemCollection> childItems) {
|
public static void implodeChildList(ItemCollection workitem, List<ItemCollection> childItems) {
|
||||||
|
|
@ -111,7 +107,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the List of ItemCollections back into a List of Map elements
|
* Convert the List of ItemCollections back into a List of Map elements
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes" })
|
@SuppressWarnings({ "rawtypes" })
|
||||||
|
|
@ -130,11 +126,10 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode berechnet das feld 'invoice.positions' welches eine Valueliste
|
* Diese Methode berechnet das feld 'invoice.positions' welches eine Valueliste
|
||||||
* mit allen Positionsnummern aus dem Childliste enthält.
|
* mit allen Positionsnummern aus dem Childliste enthält. Es wird sowohl für
|
||||||
* Es wird sowohl für Ausgangs wie Eingangsrechnungen genutzt.
|
* Ausgangs wie Eingangsrechnungen genutzt. Das feld wird indiziert, so dass
|
||||||
* Das feld wird indiziert, so dass eine gezielte Suche nach positiosnummern
|
* eine gezielte Suche nach positiosnummern möglich ist.
|
||||||
* möglich ist.
|
*
|
||||||
*
|
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
public static void updateInvoicePositions(ItemCollection workitem) {
|
public static void updateInvoicePositions(ItemCollection workitem) {
|
||||||
|
|
@ -162,9 +157,9 @@ public class InvoiceUtil {
|
||||||
/**
|
/**
|
||||||
* Diese Hilfsmethode harmonisiert die Debitoren/Kreditoren ID von Cargosoft und
|
* Diese Hilfsmethode harmonisiert die Debitoren/Kreditoren ID von Cargosoft und
|
||||||
* liefert eine Geschäftspartner ID zurück.
|
* liefert eine Geschäftspartner ID zurück.
|
||||||
*
|
*
|
||||||
* Aus Kreditor K70153 und Debitor D10153 wird die einheitliche ID: BP0153
|
* Aus Kreditor K70153 und Debitor D10153 wird die einheitliche ID: BP0153
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -188,7 +183,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Hilfmethode berechnet die BusinessPartner id aus einer Invoice
|
* Diese Hilfmethode berechnet die BusinessPartner id aus einer Invoice
|
||||||
*
|
*
|
||||||
* @param Invoice
|
* @param Invoice
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -204,7 +199,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Hilfmethode berechnet die BusinessPartner Namen aus einer Invoice
|
* Diese Hilfmethode berechnet die BusinessPartner Namen aus einer Invoice
|
||||||
*
|
*
|
||||||
* @param Invoice
|
* @param Invoice
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -223,7 +218,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt true zurück wenn es sich um eine Kreditoren Rechnung/Gutschrift handelt.
|
* Gibt true zurück wenn es sich um eine Kreditoren Rechnung/Gutschrift handelt.
|
||||||
*
|
*
|
||||||
* @param invoice
|
* @param invoice
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -238,7 +233,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt true zurück wenn es sich um eine Kreditoren Sachrechnung handelt.
|
* Gibt true zurück wenn es sich um eine Kreditoren Sachrechnung handelt.
|
||||||
*
|
*
|
||||||
* @param invoice
|
* @param invoice
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -252,7 +247,7 @@ public class InvoiceUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt true zurück wenn es sich um eine Debitoren Rechnung/Gutschrift handelt.
|
* Gibt true zurück wenn es sich um eine Debitoren Rechnung/Gutschrift handelt.
|
||||||
*
|
*
|
||||||
* @param invoice
|
* @param invoice
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import jakarta.inject.Named;
|
||||||
* errechnet der Controller die selectieren Invoices und verknpüft diese final
|
* errechnet der Controller die selectieren Invoices und verknpüft diese final
|
||||||
* mit dem Zahlungseingang.
|
* mit dem Zahlungseingang.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -74,8 +74,7 @@ public class OPListController implements Serializable {
|
||||||
* Diese Methode wird für Zahlungseingänge und Mahnläufe verwendet.
|
* Diese Methode wird für Zahlungseingänge und Mahnläufe verwendet.
|
||||||
* <p>
|
* <p>
|
||||||
* Die Methode liefert die Rechnungen zur gegebenen dbtrNumber. Die Methode
|
* Die Methode liefert die Rechnungen zur gegebenen dbtrNumber. Die Methode
|
||||||
* nutzt
|
* nutzt einen lokalen cache um die Zugriffe zu beschleunigen.
|
||||||
* einen lokalen cache um die Zugriffe zu beschleunigen.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Befindet sich ein Zahlungseingang in Erstellung (Task=1000) werden alle
|
* Befindet sich ein Zahlungseingang in Erstellung (Task=1000) werden alle
|
||||||
* offenen Rechnungen geholt.
|
* offenen Rechnungen geholt.
|
||||||
|
|
@ -90,8 +89,8 @@ public class OPListController implements Serializable {
|
||||||
* will.
|
* will.
|
||||||
* <p>
|
* <p>
|
||||||
* Beim Mahnlauf werden Inkasso Rechnungen ausgenommen.
|
* Beim Mahnlauf werden Inkasso Rechnungen ausgenommen.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param _dbtrNumber
|
* @param _dbtrNumber
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -150,7 +149,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Zahlugnseingang?
|
* Zahlugnseingang?
|
||||||
*
|
*
|
||||||
* Wir berechnen den saldo.
|
* Wir berechnen den saldo.
|
||||||
*/
|
*/
|
||||||
if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) {
|
if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) {
|
||||||
|
|
@ -172,10 +171,10 @@ public class OPListController implements Serializable {
|
||||||
* Bei einem Mahnlauf selektieren wir alle Rechnungne immer vor. Das ist eine
|
* Bei einem Mahnlauf selektieren wir alle Rechnungne immer vor. Das ist eine
|
||||||
* Anforderung von AGL Der Benutzer kann dann einzelne Rechnungen wieder
|
* Anforderung von AGL Der Benutzer kann dann einzelne Rechnungen wieder
|
||||||
* abwählen.
|
* abwählen.
|
||||||
*
|
*
|
||||||
* Eine Ausnahme ist hier nur wenn jemand auf Speichern oder mahnen drückt
|
* Eine Ausnahme ist hier nur wenn jemand auf Speichern oder mahnen drückt
|
||||||
* (Event = 10|20). Dann ändern wir die Liste nicht!
|
* (Event = 10|20). Dann ändern wir die Liste nicht!
|
||||||
*
|
*
|
||||||
* Hinweis: in der Liste befinden sich keine Inkasso Rechnungen, da man diese
|
* Hinweis: in der Liste befinden sich keine Inkasso Rechnungen, da man diese
|
||||||
* nicht anwählen kann.
|
* nicht anwählen kann.
|
||||||
*/
|
*/
|
||||||
|
|
@ -185,8 +184,7 @@ public class OPListController implements Serializable {
|
||||||
// einer Rechnung mit dem Event 100 (Mahnlauf erstellen) kommen, oder
|
// einer Rechnung mit dem Event 100 (Mahnlauf erstellen) kommen, oder
|
||||||
// wenn der Mahnlauf von außen gerate eben neu erzeugt wurde
|
// wenn der Mahnlauf von außen gerate eben neu erzeugt wurde
|
||||||
if (workflowController.getWorkitem().getItemValueInteger("$lastevent") == 100
|
if (workflowController.getWorkitem().getItemValueInteger("$lastevent") == 100
|
||||||
||
|
|| workflowController.getWorkitem().getItemValueInteger("$lastevent") == 0) {
|
||||||
workflowController.getWorkitem().getItemValueInteger("$lastevent") == 0) {
|
|
||||||
List<String> intialSelection = new ArrayList<String>();
|
List<String> intialSelection = new ArrayList<String>();
|
||||||
for (ItemCollection invoice : invoiceList) {
|
for (ItemCollection invoice : invoiceList) {
|
||||||
// ist die Rechnung fällig?
|
// ist die Rechnung fällig?
|
||||||
|
|
@ -247,7 +245,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On Before Process we store the selected invoices in $worktiemRef
|
* On Before Process we store the selected invoices in $worktiemRef
|
||||||
*
|
*
|
||||||
* @param workflowEvent
|
* @param workflowEvent
|
||||||
*/
|
*/
|
||||||
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) {
|
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) {
|
||||||
|
|
@ -299,7 +297,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode delegates to ZahlungseingangServcie
|
* Hilfsmethode delegates to ZahlungseingangServcie
|
||||||
*
|
*
|
||||||
* @param payment
|
* @param payment
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -309,7 +307,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet den gesammten OP Saldo
|
* Berechnet den gesammten OP Saldo
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double calculateInvoiceTotal() {
|
public double calculateInvoiceTotal() {
|
||||||
|
|
@ -323,10 +321,10 @@ public class OPListController implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet die Summer aller Rechnungen zu einer Währung.
|
* Berechnet die Summer aller Rechnungen zu einer Währung. Es werden nur
|
||||||
* Es werden nur Rechnungen berücksichtigt, deren Haupt Währung der übergebenen
|
* Rechnungen berücksichtigt, deren Haupt Währung der übergebenen Währung
|
||||||
* Währung entspricht.
|
* entspricht.
|
||||||
*
|
*
|
||||||
* @param currency
|
* @param currency
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -344,7 +342,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet den gesamten OP Saldo
|
* Berechnet den gesamten OP Saldo
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double calculateInvoiceSaldo() {
|
public double calculateInvoiceSaldo() {
|
||||||
|
|
@ -361,7 +359,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet den noch offenen Differenz vom Zahlbetrag
|
* Berechnet den noch offenen Differenz vom Zahlbetrag
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double calculatePaymentDifference() {
|
public double calculatePaymentDifference() {
|
||||||
|
|
@ -379,7 +377,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet den Zahlbetrag in EUR bei Fremdwärungen
|
* Berechnet den Zahlbetrag in EUR bei Fremdwärungen
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double calculatePaymentSaldoEUR() {
|
public double calculatePaymentSaldoEUR() {
|
||||||
|
|
@ -401,7 +399,7 @@ public class OPListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the reminder date is today or in the past
|
* Returns true if the reminder date is today or in the past
|
||||||
*
|
*
|
||||||
* @param uniqueid
|
* @param uniqueid
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import jakarta.inject.Inject;
|
||||||
* Der OPListExportAdapter exportiert eine Excel Datei mit allen offenen
|
* Der OPListExportAdapter exportiert eine Excel Datei mit allen offenen
|
||||||
* Rechnungen gruppiert nach Debitor. Es werden alle Ausgehenden Währungen
|
* Rechnungen gruppiert nach Debitor. Es werden alle Ausgehenden Währungen
|
||||||
* berücksichtigt und ab Spalte H eingefügt.
|
* berücksichtigt und ab Spalte H eingefügt.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<opliste name="textblock">textblock-ref</opliste>
|
<opliste name="textblock">textblock-ref</opliste>
|
||||||
|
|
@ -46,16 +46,16 @@ import jakarta.inject.Inject;
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
|
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
|
||||||
* (siehe POIFineReplaceAdapter).
|
* (siehe POIFineReplaceAdapter).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilennummer
|
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilennummer
|
||||||
* 12 eingefügt werden.
|
* 12 eingefügt werden.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Abschliessend werden Summen Formeln in Zeile 14 für jede Währung eingefügt.
|
* Abschliessend werden Summen Formeln in Zeile 14 für jede Währung eingefügt.
|
||||||
*
|
*
|
||||||
* Der Fälligkeitszeitrum von 21 Tagen kann über den Parameter
|
* Der Fälligkeitszeitrum von 21 Tagen kann über den Parameter
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -78,7 +78,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Zahlungsavis and adds a reference
|
* This method finds or create the Zahlungsavis and adds a reference
|
||||||
* ($workitemref) to the current invoice.
|
* ($workitemref) to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -95,9 +95,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the template options
|
// read the template options
|
||||||
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste",
|
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste", document, false);
|
||||||
document,
|
|
||||||
false);
|
|
||||||
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
|
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||||
"missing opliste configuration in model event - please check model configuration");
|
"missing opliste configuration in model event - please check model configuration");
|
||||||
|
|
@ -132,13 +130,11 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
doc.write(byteArrayOutputStream);
|
doc.write(byteArrayOutputStream);
|
||||||
|
|
||||||
byte[] newContent = byteArrayOutputStream.toByteArray();
|
byte[] newContent = byteArrayOutputStream.toByteArray();
|
||||||
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
|
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
|
||||||
null);
|
|
||||||
document.addFileData(fileDataNew);
|
document.addFileData(fileDataNew);
|
||||||
logger.finest("......new document added");
|
logger.finest("......new document added");
|
||||||
} catch (IOException | QueryException e) {
|
} catch (IOException | QueryException e) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"failed to update opliste: " + e.getMessage());
|
"failed to update opliste: " + e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
|
|
@ -157,8 +153,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
} catch (
|
} catch (
|
||||||
|
|
||||||
PluginException e) {
|
PluginException e) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"failed to update op-liste: " + e.getMessage());
|
"failed to update op-liste: " + e.getMessage());
|
||||||
}
|
}
|
||||||
logger.fine("... completed!");
|
logger.fine("... completed!");
|
||||||
|
|
@ -169,8 +164,8 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* EIne OP Liste kann für eine oder mehrere Währungen erstellt werden. Diese
|
* EIne OP Liste kann für eine oder mehrere Währungen erstellt werden. Diese
|
||||||
* Hilfsmethode fügt die Spalten anhand der Währungen ein.
|
* Hilfsmethode fügt die Spalten anhand der Währungen ein.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param sheet
|
* @param sheet
|
||||||
* @param currencyList
|
* @param currencyList
|
||||||
*/
|
*/
|
||||||
|
|
@ -206,13 +201,12 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
* <p>
|
* <p>
|
||||||
* The named cell 'TOTAL' should contain the summary formula. It will be
|
* The named cell 'TOTAL' should contain the summary formula. It will be
|
||||||
* evaluated at the end.
|
* evaluated at the end.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*/
|
*/
|
||||||
private void insertInvoiceRows(XSSFSheet sheet, ItemCollection document, String fileName, boolean filter,
|
private void insertInvoiceRows(XSSFSheet sheet, ItemCollection document, String fileName, boolean filter,
|
||||||
List<String> currencyList)
|
List<String> currencyList) throws PluginException, QueryException {
|
||||||
throws PluginException, QueryException {
|
|
||||||
|
|
||||||
String spaceID = document.getItemValueString("space.ref");
|
String spaceID = document.getItemValueString("space.ref");
|
||||||
logger.fine("... space.ref=" + spaceID + " ...grouping invoices by spaceid....");
|
logger.fine("... space.ref=" + spaceID + " ...grouping invoices by spaceid....");
|
||||||
|
|
@ -344,17 +338,15 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method loads a text-block for a specified ref and appends the named
|
* This method loads a text-block for a specified ref and appends the named
|
||||||
* fileData object of this document.
|
* fileData object of this document.
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
|
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
|
||||||
String targetName)
|
String targetName) throws PluginException {
|
||||||
throws PluginException {
|
|
||||||
|
|
||||||
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
|
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"invalid POI configuration in model event - textblock/template reference not defined!");
|
"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?
|
// do we found the document?
|
||||||
if (fileData == null) {
|
if (fileData == null) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
"invalid POI configuration in model event - template=" + template + " not found!");
|
||||||
"invalid POI configuration in model event - template=" + template
|
|
||||||
+ " not found!");
|
|
||||||
}
|
}
|
||||||
fileData.setName(targetName);
|
fileData.setName(targetName);
|
||||||
// append document
|
// append document
|
||||||
|
|
@ -377,10 +367,10 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode gruppiert eine Rechnungsliste nach Debitorennummern
|
* Diese Methode gruppiert eine Rechnungsliste nach Debitorennummern
|
||||||
*
|
*
|
||||||
* Falls 'filter==true' werden nur Rechnungen ab der 2. Mahnung oder mit einer
|
* Falls 'filter==true' werden nur Rechnungen ab der 2. Mahnung oder mit einer
|
||||||
* Fälligkeit >10 Tage ausgegeben. Dieses Flag wird im Workflowmodell gesetzt
|
* Fälligkeit >10 Tage ausgegeben. Dieses Flag wird im Workflowmodell gesetzt
|
||||||
*
|
*
|
||||||
* @param spaceID
|
* @param spaceID
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ import jakarta.inject.Inject;
|
||||||
* Der OPListExportAdapterByWeek ist ählnlich dem Der OPListExportAdapter. Er
|
* Der OPListExportAdapterByWeek ist ählnlich dem Der OPListExportAdapter. Er
|
||||||
* erzeugt eine Excel tabelle mit allen offenen Rechnungen und gruppiert diese
|
* erzeugt eine Excel tabelle mit allen offenen Rechnungen und gruppiert diese
|
||||||
* nach Abteilungen und KW
|
* nach Abteilungen und KW
|
||||||
*
|
*
|
||||||
* Der OPListExportAdapterByWeek importiert eine Excel Datei aus einem Textblock
|
* Der OPListExportAdapterByWeek importiert eine Excel Datei aus einem Textblock
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<opliste name="textblock">textblock-ref</opliste>
|
<opliste name="textblock">textblock-ref</opliste>
|
||||||
|
|
@ -59,14 +59,14 @@ import jakarta.inject.Inject;
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
|
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
|
||||||
* (siehe POIFineReplaceAdapter).
|
* (siehe POIFineReplaceAdapter).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
|
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
|
||||||
* 16 eingefügt werden.
|
* 16 eingefügt werden.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -97,7 +97,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Zahlungsavis and adds a reference
|
* This method finds or create the Zahlungsavis and adds a reference
|
||||||
* ($workitemref) to the current invoice.
|
* ($workitemref) to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -119,9 +119,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
Collections.sort(spaces, new ItemCollectionComparator("space.name", true));
|
Collections.sort(spaces, new ItemCollectionComparator("space.name", true));
|
||||||
|
|
||||||
// read the template options
|
// read the template options
|
||||||
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste",
|
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste", document, false);
|
||||||
document,
|
|
||||||
false);
|
|
||||||
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
|
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||||
"missing opliste configuration in model event - please check model configuration");
|
"missing opliste configuration in model event - please check model configuration");
|
||||||
|
|
@ -155,14 +153,12 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
doc.write(byteArrayOutputStream);
|
doc.write(byteArrayOutputStream);
|
||||||
|
|
||||||
byte[] newContent = byteArrayOutputStream.toByteArray();
|
byte[] newContent = byteArrayOutputStream.toByteArray();
|
||||||
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
|
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
|
||||||
null);
|
|
||||||
document.addFileData(fileDataNew);
|
document.addFileData(fileDataNew);
|
||||||
logger.finest("......new document added");
|
logger.finest("......new document added");
|
||||||
|
|
||||||
} catch (IOException | QueryException e) {
|
} catch (IOException | QueryException e) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"failed to update opliste: " + e.getMessage());
|
"failed to update opliste: " + e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
|
|
@ -180,8 +176,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
} catch (
|
} catch (
|
||||||
|
|
||||||
PluginException e) {
|
PluginException e) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"failed to update op-liste: " + e.getMessage());
|
"failed to update op-liste: " + e.getMessage());
|
||||||
}
|
}
|
||||||
logger.fine("... completed!");
|
logger.fine("... completed!");
|
||||||
|
|
@ -193,7 +188,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* EIne OP Liste kann für eine oder mehrere Währungen erstellt werden. Diese
|
* EIne OP Liste kann für eine oder mehrere Währungen erstellt werden. Diese
|
||||||
* Hilfsmethode fügt die Spalten anhand der Währungen für jede Abteilung ein.
|
* Hilfsmethode fügt die Spalten anhand der Währungen für jede Abteilung ein.
|
||||||
*
|
*
|
||||||
* @param sheet
|
* @param sheet
|
||||||
* @param currencyList
|
* @param currencyList
|
||||||
*/
|
*/
|
||||||
|
|
@ -249,13 +244,12 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
* <p>
|
* <p>
|
||||||
* The named cell 'TOTAL' should contain the summary formula. It will be
|
* The named cell 'TOTAL' should contain the summary formula. It will be
|
||||||
* evaluated at the end.
|
* evaluated at the end.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*/
|
*/
|
||||||
private void insertInvoiceRows(XSSFWorkbook doc, XSSFSheet sheet, List<String> currencyList,
|
private void insertInvoiceRows(XSSFWorkbook doc, XSSFSheet sheet, List<String> currencyList,
|
||||||
List<ItemCollection> spaces)
|
List<ItemCollection> spaces) throws PluginException, QueryException {
|
||||||
throws PluginException, QueryException {
|
|
||||||
|
|
||||||
List<String> spaceNames = new ArrayList<String>();
|
List<String> spaceNames = new ArrayList<String>();
|
||||||
|
|
||||||
|
|
@ -285,8 +279,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- Phase 1 -------------------------------------------------------
|
* --- Phase 1 ------------------------------------------------------- Im
|
||||||
* Im folgenden gruppieren wir die Rechnungen nach Woche
|
* folgenden gruppieren wir die Rechnungen nach Woche
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// XSSFCell cellKWTotalReference = referenceRowTotal.getCell(14);
|
// XSSFCell cellKWTotalReference = referenceRowTotal.getCell(14);
|
||||||
|
|
@ -306,10 +300,10 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
totalDataMapUeberFaellig.put("TOTAL", new TotalInvoiceData("TOTAL"));
|
totalDataMapUeberFaellig.put("TOTAL", new TotalInvoiceData("TOTAL"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- Phase 3 -------------------------------------------------------
|
* --- Phase 3 ------------------------------------------------------- now build
|
||||||
* now build a new row for each week and print out the collected invoice data
|
* a new row for each week and print out the collected invoice data first
|
||||||
* first iterate over all objects and collect all known weeks and sort them into
|
* iterate over all objects and collect all known weeks and sort them into a
|
||||||
* a ordered list....
|
* ordered list....
|
||||||
*/
|
*/
|
||||||
List<String> sortedWeekList = new ArrayList<String>();
|
List<String> sortedWeekList = new ArrayList<String>();
|
||||||
Iterator<Map.Entry<String, WeekInvoiceData>> iterator = weekDataMap.entrySet().iterator();
|
Iterator<Map.Entry<String, WeekInvoiceData>> iterator = weekDataMap.entrySet().iterator();
|
||||||
|
|
@ -323,9 +317,9 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
Collections.sort(sortedWeekList);
|
Collections.sort(sortedWeekList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- Phase 4 -------------------------------------------------------
|
* --- Phase 4 ------------------------------------------------------- Nun
|
||||||
* Nun müssen wir so viele Zeilen nach unten schieben wie wir gleich einfügen.
|
* müssen wir so viele Zeilen nach unten schieben wie wir gleich einfügen. Dazu
|
||||||
* Dazu müssen wir kurz einen Probelauf machen um die geplante Anzahl zu
|
* müssen wir kurz einen Probelauf machen um die geplante Anzahl zu
|
||||||
* errechnen....
|
* errechnen....
|
||||||
*/
|
*/
|
||||||
int rowPos = 11;
|
int rowPos = 11;
|
||||||
|
|
@ -333,8 +327,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
sheet.shiftRows(rowPos + 1, 2999, insertCount, true, true);
|
sheet.shiftRows(rowPos + 1, 2999, insertCount, true, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- Phase 5 -------------------------------------------------------
|
* --- Phase 5 ------------------------------------------------------- Jetzt
|
||||||
* Jetzt Zahlen Zeile für Zeile einfügen....
|
* Zahlen Zeile für Zeile einfügen....
|
||||||
*/
|
*/
|
||||||
boolean ueberFaellig = true;
|
boolean ueberFaellig = true;
|
||||||
for (String week : sortedWeekList) {
|
for (String week : sortedWeekList) {
|
||||||
|
|
@ -399,9 +393,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- Phase 6 -------------------------------------------------------
|
* --- Phase 6 ------------------------------------------------------- now lets
|
||||||
* now lets update the totals...
|
* update the totals... Überfällig
|
||||||
* Überfällig
|
|
||||||
*/
|
*/
|
||||||
int _rowNo = sortedWeekList.size() + 14;
|
int _rowNo = sortedWeekList.size() + 14;
|
||||||
XSSFRow rowUeberFaellig = sheet.getRow(_rowNo);
|
XSSFRow rowUeberFaellig = sheet.getRow(_rowNo);
|
||||||
|
|
@ -460,16 +453,14 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode gruppiert eine Rechnungsliste nach Kalenderwoche
|
* Diese Methode gruppiert eine Rechnungsliste nach Kalenderwoche
|
||||||
*
|
*
|
||||||
* @param spaceID - Space Ref to select a list of invoices associated with
|
* @param spaceID - Space Ref to select a list of invoices associated with
|
||||||
* a
|
* a space
|
||||||
* space
|
|
||||||
* @param weekDataCache - a local cache storing all invoices by week
|
* @param weekDataCache - a local cache storing all invoices by week
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void groupInvoicesByWeek(String spaceID, String spaceName,
|
private void groupInvoicesByWeek(String spaceID, String spaceName, Map<String, WeekInvoiceData> weekDataCache) {
|
||||||
Map<String, WeekInvoiceData> weekDataCache) {
|
|
||||||
|
|
||||||
logger.info("...group invoices for " + spaceName + "/" + spaceID);
|
logger.info("...group invoices for " + spaceName + "/" + spaceID);
|
||||||
try {
|
try {
|
||||||
|
|
@ -482,9 +473,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
// compute Week
|
// compute Week
|
||||||
Date dueDate = invoice.getItemValueDate("invoice.duedate");
|
Date dueDate = invoice.getItemValueDate("invoice.duedate");
|
||||||
|
|
||||||
LocalDate localDate = dueDate.toInstant()
|
LocalDate localDate = dueDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||||
.atZone(ZoneId.systemDefault())
|
|
||||||
.toLocalDate();
|
|
||||||
int weekNumber = localDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
|
int weekNumber = localDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
|
||||||
int weekBasedYear = localDate.get(IsoFields.WEEK_BASED_YEAR);
|
int weekBasedYear = localDate.get(IsoFields.WEEK_BASED_YEAR);
|
||||||
String weekCategory = weekBasedYear + "/" + String.format("%02d", weekNumber);
|
String weekCategory = weekBasedYear + "/" + String.format("%02d", weekNumber);
|
||||||
|
|
@ -521,17 +510,15 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method loads a text-block for a specified ref and appends the named
|
* This method loads a text-block for a specified ref and appends the named
|
||||||
* fileData object of this document.
|
* fileData object of this document.
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
|
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
|
||||||
String targetName)
|
String targetName) throws PluginException {
|
||||||
throws PluginException {
|
|
||||||
|
|
||||||
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
|
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
|
||||||
"invalid POI configuration in model event - textblock/template reference not defined!");
|
"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?
|
// do we found the document?
|
||||||
if (fileData == null) {
|
if (fileData == null) {
|
||||||
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
|
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
|
||||||
InvoiceService.ERROR_CONFIG,
|
"invalid POI configuration in model event - template=" + template + " not found!");
|
||||||
"invalid POI configuration in model event - template=" + template
|
|
||||||
+ " not found!");
|
|
||||||
}
|
}
|
||||||
fileData.setName(targetName);
|
fileData.setName(targetName);
|
||||||
// append document
|
// append document
|
||||||
|
|
@ -555,8 +540,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data Element for invoice totals per week and space.
|
* Data Element for invoice totals per week and space. The object holds multiple
|
||||||
* The object holds multiple currencies.
|
* currencies.
|
||||||
*/
|
*/
|
||||||
class WeekInvoiceData {
|
class WeekInvoiceData {
|
||||||
|
|
||||||
|
|
@ -601,8 +586,8 @@ class WeekInvoiceData {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data Element for invoice totals per space.
|
* Data Element for invoice totals per space. The object holds multiple
|
||||||
* The object holds multiple currencies.
|
* currencies.
|
||||||
*/
|
*/
|
||||||
class TotalInvoiceData {
|
class TotalInvoiceData {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,26 @@ package com.alexanderlogistics;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
@ -34,44 +34,43 @@ import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The OPListExportController is used to configure the OpListeExporterService.
|
* The OPListExportController is used to configure the OpListeExporterService.
|
||||||
* This service is
|
* This service is used to export workitems.
|
||||||
* used to export workitems.
|
|
||||||
* <p>
|
* <p>
|
||||||
* The Controller creates a configuration entity "type=configuration;
|
* The Controller creates a configuration entity "type=configuration;
|
||||||
* txtname=OPLIST_EXPORT_CONFIGURATION".
|
* txtname=OPLIST_EXPORT_CONFIGURATION".
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Named(value = "oplistExportController")
|
@Named(value = "oplistExportController")
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class OPListExportController extends SchedulerController {
|
public class OPListExportController extends SchedulerController {
|
||||||
|
|
||||||
public static final String OPLIST_EXPORT_CONFIGURATION = "OPLIST_EXPORT_CONFIGURATION";
|
public static final String OPLIST_EXPORT_CONFIGURATION = "OPLIST_EXPORT_CONFIGURATION";
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(OPListExportController.class.getName());
|
private static Logger logger = Logger.getLogger(OPListExportController.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
OPListExportScheduler opListExportScheduler;
|
OPListExportScheduler opListExportScheduler;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return OPLIST_EXPORT_CONFIGURATION;
|
return OPLIST_EXPORT_CONFIGURATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sepa scheduler class name. This name depends on the _export_type.
|
* Returns the sepa scheduler class name. This name depends on the _export_type.
|
||||||
*
|
*
|
||||||
* There are two export interfaces available - csv and XML
|
* There are two export interfaces available - csv and XML
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getSchedulerClass() {
|
public String getSchedulerClass() {
|
||||||
String schedulerClass = OPListExportScheduler.class.getName();
|
String schedulerClass = OPListExportScheduler.class.getName();
|
||||||
logger.finest("...... scheduler: " + schedulerClass);
|
logger.finest("...... scheduler: " + schedulerClass);
|
||||||
return schedulerClass;
|
return schedulerClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -61,10 +61,10 @@ import jakarta.inject.Inject;
|
||||||
* The class implements the interface
|
* The class implements the interface
|
||||||
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
|
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
|
||||||
* combination with the Imxis-Workflow Scheduler Service.
|
* combination with the Imxis-Workflow Scheduler Service.
|
||||||
*
|
*
|
||||||
* @see SchedulerService
|
* @see SchedulerService
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class OPListExportScheduler implements Scheduler {
|
public class OPListExportScheduler implements Scheduler {
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ public class OPListExportScheduler implements Scheduler {
|
||||||
/**
|
/**
|
||||||
* This is the method which processes the timeout event depending on the running
|
* This is the method which processes the timeout event depending on the running
|
||||||
* timer settings.
|
* timer settings.
|
||||||
*
|
*
|
||||||
* @param timer
|
* @param timer
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*/
|
*/
|
||||||
|
|
@ -131,7 +131,7 @@ public class OPListExportScheduler implements Scheduler {
|
||||||
/**
|
/**
|
||||||
* Prüfen ob es Rechnungen in diesem Space gibt die entweder die 2. Mahnstufe
|
* Prüfen ob es Rechnungen in diesem Space gibt die entweder die 2. Mahnstufe
|
||||||
* erreicht haben oder deren Fälligkeit um mehr als 21 Tage überschritten ist.
|
* erreicht haben oder deren Fälligkeit um mehr als 21 Tage überschritten ist.
|
||||||
*
|
*
|
||||||
* @param space
|
* @param space
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -139,8 +139,8 @@ public class OPListExportScheduler implements Scheduler {
|
||||||
List<ItemCollection> invoices = new ArrayList<ItemCollection>();
|
List<ItemCollection> invoices = new ArrayList<ItemCollection>();
|
||||||
try {
|
try {
|
||||||
invoices = documentService.find(
|
invoices = documentService.find(
|
||||||
"$modelversion:rechnungsausgang-* AND type:workitem AND $uniqueidref:" + space.getUniqueID(),
|
"$modelversion:rechnungsausgang-* AND type:workitem AND $uniqueidref:" + space.getUniqueID(), 999,
|
||||||
999, 0);
|
0);
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
logger.warning("Failed to compute invoice list: " + e.getMessage());
|
logger.warning("Failed to compute invoice list: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
@ -168,7 +168,7 @@ public class OPListExportScheduler implements Scheduler {
|
||||||
/**
|
/**
|
||||||
* Creates a new log entry stored in the item _scheduler_log. The log can be
|
* Creates a new log entry stored in the item _scheduler_log. The log can be
|
||||||
* writen optional to the configuraiton and the workitem
|
* writen optional to the configuraiton and the workitem
|
||||||
*
|
*
|
||||||
* @param message
|
* @param message
|
||||||
* @param configuration
|
* @param configuration
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -17,123 +17,122 @@ import jakarta.inject.Inject;
|
||||||
/**
|
/**
|
||||||
* Der RenameFilenamesAdapter kann optional eingesetzt werden. Dieser Adapter
|
* Der RenameFilenamesAdapter kann optional eingesetzt werden. Dieser Adapter
|
||||||
* verändert den Dateinamen von angehangenen Rechnungen
|
* verändert den Dateinamen von angehangenen Rechnungen
|
||||||
*
|
*
|
||||||
* Der Adapter wir beispielweise in DWC eingesetzt bevor die Dateien in einen
|
* Der Adapter wir beispielweise in DWC eingesetzt bevor die Dateien in einen
|
||||||
* FTP Server hochgeladen werden.
|
* FTP Server hochgeladen werden.
|
||||||
*
|
*
|
||||||
* Die Dateinamen werden vom System berechnet.
|
* Die Dateinamen werden vom System berechnet.
|
||||||
*
|
*
|
||||||
* sequencenumber + "_" +invoice.positions+".pdf"
|
* sequencenumber + "_" +invoice.positions+".pdf"
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Bei Sachrechnungen
|
* Bei Sachrechnungen
|
||||||
*
|
*
|
||||||
* sequencenumber + "_" + invoice.number.stripped + ".pdf"
|
* sequencenumber + "_" + invoice.number.stripped + ".pdf" wird das
|
||||||
* wird das Rechnungsdatum verwendet um die Buchungsperiode zu berechnen.
|
* Rechnungsdatum verwendet um die Buchungsperiode zu berechnen.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RenameFilenamesAdapter implements SignalAdapter {
|
public class RenameFilenamesAdapter implements SignalAdapter {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(RenameFilenamesAdapter.class.getName());
|
private static Logger logger = Logger.getLogger(RenameFilenamesAdapter.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SnapshotService snapshotService;
|
SnapshotService snapshotService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename Filenames
|
* Rename Filenames
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection execute(ItemCollection workitem, ItemCollection event)
|
public ItemCollection execute(ItemCollection workitem, ItemCollection event)
|
||||||
throws AdapterException, PluginException {
|
throws AdapterException, PluginException {
|
||||||
|
|
||||||
int fileNameCounter = 0; // for multiple files
|
int fileNameCounter = 0; // for multiple files
|
||||||
List<FileData> fileDataSet = workitem.getFileData();
|
List<FileData> fileDataSet = workitem.getFileData();
|
||||||
for (FileData fileData : fileDataSet) {
|
for (FileData fileData : fileDataSet) {
|
||||||
String fileName = fileData.getName();
|
String fileName = fileData.getName();
|
||||||
// only PDF files and X-Rechnung
|
// only PDF files and X-Rechnung
|
||||||
if ((fileName.toLowerCase().endsWith(".pdf")
|
if ((fileName.toLowerCase().endsWith(".pdf") || fileName.toLowerCase().endsWith(".xml"))) {
|
||||||
|| fileName.toLowerCase().endsWith(".xml"))) {
|
|
||||||
|
|
||||||
// Build new Filename
|
// Build new Filename
|
||||||
String newFileName = buildFileName(fileName, workitem, fileNameCounter);
|
String newFileName = buildFileName(fileName, workitem, fileNameCounter);
|
||||||
if (!newFileName.equals(fileName)) {
|
if (!newFileName.equals(fileName)) {
|
||||||
logger.info("Rename file name " + fileName + " -> " + newFileName);
|
logger.info("Rename file name " + fileName + " -> " + newFileName);
|
||||||
// do we have content
|
// do we have content
|
||||||
if (fileData.getContent().length < 10) {
|
if (fileData.getContent().length < 10) {
|
||||||
// fetch snaphot data
|
// fetch snaphot data
|
||||||
FileData snapShotFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), fileName);
|
FileData snapShotFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), fileName);
|
||||||
// remove old data
|
// remove old data
|
||||||
workitem.removeFile(fileName);
|
workitem.removeFile(fileName);
|
||||||
snapShotFileData.setName(newFileName);
|
snapShotFileData.setName(newFileName);
|
||||||
workitem.addFileData(snapShotFileData);
|
workitem.addFileData(snapShotFileData);
|
||||||
} else {
|
} else {
|
||||||
fileData.setName(newFileName);
|
fileData.setName(newFileName);
|
||||||
}
|
}
|
||||||
fileNameCounter++;
|
fileNameCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update FTP Target path information
|
// Update FTP Target path information
|
||||||
String targetPath = "";
|
String targetPath = "";
|
||||||
if (InvoiceUtil.isCreditorInvoice(workitem)) {
|
if (InvoiceUtil.isCreditorInvoice(workitem)) {
|
||||||
targetPath = "invoice-in/";
|
targetPath = "invoice-in/";
|
||||||
String bookingPath = workitem.getItemValueString("invoice.period");
|
String bookingPath = workitem.getItemValueString("invoice.period");
|
||||||
// Sachrechnung
|
// Sachrechnung
|
||||||
if (bookingPath.isEmpty()) {
|
if (bookingPath.isEmpty()) {
|
||||||
// build period from invoice.date
|
// build period from invoice.date
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
|
||||||
LocalDate invoiceDate = workitem.getItemValueLocalDate("invoice.date");
|
LocalDate invoiceDate = workitem.getItemValueLocalDate("invoice.date");
|
||||||
bookingPath = invoiceDate.format(formatter);
|
bookingPath = invoiceDate.format(formatter);
|
||||||
}
|
}
|
||||||
if (bookingPath.length() > 4) {
|
if (bookingPath.length() > 4) {
|
||||||
targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
|
targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targetPath = "invoice-out/";
|
targetPath = "invoice-out/";
|
||||||
String bookingPath = workitem.getItemValueString("invoice.bookingperiod");
|
String bookingPath = workitem.getItemValueString("invoice.bookingperiod");
|
||||||
targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
|
targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
workitem.setItemValue("ftp.target.path", targetPath + "/");
|
workitem.setItemValue("ftp.target.path", targetPath + "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Baut einen Filenamen aus verschiedenen Attributen zusammen.
|
* Baut einen Filenamen aus verschiedenen Attributen zusammen.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String buildFileName(String fileName, ItemCollection workitem, int counter) {
|
private String buildFileName(String fileName, ItemCollection workitem, int counter) {
|
||||||
String result = workitem.getItemValueString("sequencenumber") + "_";
|
String result = workitem.getItemValueString("sequencenumber") + "_";
|
||||||
|
|
||||||
if (InvoiceUtil.isSachrechnung(workitem)) {
|
if (InvoiceUtil.isSachrechnung(workitem)) {
|
||||||
result = result + workitem.getItemValueString("invoice.number.stripped");
|
result = result + workitem.getItemValueString("invoice.number.stripped");
|
||||||
} else {
|
} else {
|
||||||
// für ausgangsrechnungen skippen wir die Cargosoft XML Datei
|
// für ausgangsrechnungen skippen wir die Cargosoft XML Datei
|
||||||
if (fileName.toLowerCase().endsWith(".xml")) {
|
if (fileName.toLowerCase().endsWith(".xml")) {
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
// für die PDF Datei bauen wir einen neuen Namen
|
// für die PDF Datei bauen wir einen neuen Namen
|
||||||
result = result + workitem.getItemValueString("invoice.positions");
|
result = result + workitem.getItemValueString("invoice.positions");
|
||||||
}
|
}
|
||||||
if (counter > 0) {
|
if (counter > 0) {
|
||||||
result = result + "_" + counter;
|
result = result + "_" + counter;
|
||||||
}
|
}
|
||||||
result = result + fileName.substring(fileName.lastIndexOf("."));
|
result = result + fileName.substring(fileName.lastIndexOf("."));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@ import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der SEPAExportControllerAGL dient dazu die IBAN/BIC einstellungen in
|
* Der SEPAExportControllerAGL dient dazu die IBAN/BIC einstellungen in einem
|
||||||
* einem SEPA Export zu aktualiseren. Er wird von der Form
|
* SEPA Export zu aktualiseren. Er wird von der Form sepa_export.xhtml aus per
|
||||||
* sepa_export.xhtml aus per Ajax angesteuert.
|
* Ajax angesteuert.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der SteuerListController dient dazu in einem Stuerbescheid
|
* Der SteuerListController dient dazu in einem Stuerbescheid die einzelnen
|
||||||
* die einzelnen Zeilen auszugeben.
|
* Zeilen auszugeben.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -32,7 +32,7 @@ public class SteuerListController implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt die Zeilen aus einem importierten Steuerbeleg (eAkte) zurück
|
* Gibt die Zeilen aus einem importierten Steuerbeleg (eAkte) zurück
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<ItemCollection> getRows() {
|
public List<ItemCollection> getRows() {
|
||||||
|
|
|
||||||
|
|
@ -15,165 +15,161 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Das SteuerbescheidPlugin prüft ob
|
* Das SteuerbescheidPlugin prüft ob
|
||||||
*
|
*
|
||||||
* - die ATC Nummer aus dem Steuerbescheid in einer Ausgangsrechnung gefunden
|
* - die ATC Nummer aus dem Steuerbescheid in einer Ausgangsrechnung gefunden
|
||||||
* wird ($taskID<5990)
|
* wird ($taskID<5990) - invoice.atc.number - der Betrag "invoice.total.net" -
|
||||||
* - invoice.atc.number
|
* die Währung??? - die Positionsnummer ???
|
||||||
* - der Betrag "invoice.total.net"
|
*
|
||||||
* - die Währung???
|
*
|
||||||
* - die Positionsnummer ???
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SteuerbescheidPlugin extends AbstractPlugin {
|
public class SteuerbescheidPlugin extends AbstractPlugin {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(SteuerbescheidPlugin.class.getName());
|
private static Logger logger = Logger.getLogger(SteuerbescheidPlugin.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected DocumentService documentService;
|
protected DocumentService documentService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft ob der Steuerbetrag abgerechnet ist.
|
* Prüft ob der Steuerbetrag abgerechnet ist.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
|
||||||
|
|
||||||
// Update Fälligkeit
|
// Update Fälligkeit
|
||||||
updateFaelligkeit(workitem);
|
updateFaelligkeit(workitem);
|
||||||
|
|
||||||
// Update Salden
|
// Update Salden
|
||||||
updateTotalEustZoll(workitem);
|
updateTotalEustZoll(workitem);
|
||||||
updateInvoiceSaldo(workitem);
|
updateInvoiceSaldo(workitem);
|
||||||
|
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aktualisiert die EUST/ZOLL Summen
|
* Aktualisiert die EUST/ZOLL Summen
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected void updateTotalEustZoll(ItemCollection workitem) {
|
protected void updateTotalEustZoll(ItemCollection workitem) {
|
||||||
|
|
||||||
double saldoEust = 0;
|
double saldoEust = 0;
|
||||||
double saldoZoll = 0;
|
double saldoZoll = 0;
|
||||||
List<ItemCollection> positionsTabelle = InvoiceUtil.explodeChildList(workitem);
|
List<ItemCollection> positionsTabelle = InvoiceUtil.explodeChildList(workitem);
|
||||||
for (ItemCollection pos : positionsTabelle) {
|
for (ItemCollection pos : positionsTabelle) {
|
||||||
if ("EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
if ("EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
||||||
saldoEust = saldoEust + pos.getItemValueDouble("amount");
|
saldoEust = saldoEust + pos.getItemValueDouble("amount");
|
||||||
}
|
}
|
||||||
if ("ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
if ("ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
||||||
saldoZoll = saldoZoll + pos.getItemValueDouble("amount");
|
saldoZoll = saldoZoll + pos.getItemValueDouble("amount");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
workitem.setItemValue("steuer.eust", saldoEust);
|
workitem.setItemValue("steuer.eust", saldoEust);
|
||||||
workitem.setItemValue("steuer.zoll", saldoZoll);
|
workitem.setItemValue("steuer.zoll", saldoZoll);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aktualisiert die EUST/ZOLL Fälligkeiten in den Detailtabellen
|
* Aktualisiert die EUST/ZOLL Fälligkeiten in den Detailtabellen Die Daten
|
||||||
* Die Daten kommen von der KI und werden auf die Positionsnummern gemappt.
|
* kommen von der KI und werden auf die Positionsnummern gemappt.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected void updateFaelligkeit(ItemCollection workitem) {
|
protected void updateFaelligkeit(ItemCollection workitem) {
|
||||||
|
|
||||||
boolean foundZoll = false;
|
boolean foundZoll = false;
|
||||||
boolean foundEust = false;
|
boolean foundEust = false;
|
||||||
Date datEust = null;
|
Date datEust = null;
|
||||||
Date datZoll = null;
|
Date datZoll = null;
|
||||||
// resolve datEust und datZoll from steuerbescheid.positionen ChildItems....
|
// resolve datEust und datZoll from steuerbescheid.positionen ChildItems....
|
||||||
List<ItemCollection> steuerPositionen = InvoiceUtil.explodeChildList(workitem, "steuerbescheid.position");
|
List<ItemCollection> steuerPositionen = InvoiceUtil.explodeChildList(workitem, "steuerbescheid.position");
|
||||||
for (ItemCollection steuerPos : steuerPositionen) {
|
for (ItemCollection steuerPos : steuerPositionen) {
|
||||||
if (steuerPos.getItemValueString("key").startsWith("A")) {
|
if (steuerPos.getItemValueString("key").startsWith("A")) {
|
||||||
datZoll = steuerPos.getItemValueDate("duedate");
|
datZoll = steuerPos.getItemValueDate("duedate");
|
||||||
}
|
}
|
||||||
if (steuerPos.getItemValueString("key").startsWith("B")) {
|
if (steuerPos.getItemValueString("key").startsWith("B")) {
|
||||||
datEust = steuerPos.getItemValueDate("duedate");
|
datEust = steuerPos.getItemValueDate("duedate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map fälligkeit auf die Cargosoft Positionen
|
// Map fälligkeit auf die Cargosoft Positionen
|
||||||
List<ItemCollection> rows = InvoiceUtil.explodeChildList(workitem);
|
List<ItemCollection> rows = InvoiceUtil.explodeChildList(workitem);
|
||||||
for (ItemCollection pos : rows) {
|
for (ItemCollection pos : rows) {
|
||||||
if (datZoll != null && "ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
if (datZoll != null && "ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
||||||
pos.setItemValue("duedate", datZoll);
|
pos.setItemValue("duedate", datZoll);
|
||||||
foundZoll = true;
|
foundZoll = true;
|
||||||
}
|
}
|
||||||
if (datEust != null && "EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
if (datEust != null && "EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
||||||
pos.setItemValue("duedate", datEust);
|
pos.setItemValue("duedate", datEust);
|
||||||
foundEust = true;
|
foundEust = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundEust) {
|
if (foundEust) {
|
||||||
workitem.setItemValue("steuer.eust.due", datEust);
|
workitem.setItemValue("steuer.eust.due", datEust);
|
||||||
} else {
|
} else {
|
||||||
workitem.removeItem("steuer.eust.due");
|
workitem.removeItem("steuer.eust.due");
|
||||||
}
|
}
|
||||||
if (foundZoll) {
|
if (foundZoll) {
|
||||||
workitem.setItemValue("steuer.zoll.due", datZoll);
|
workitem.setItemValue("steuer.zoll.due", datZoll);
|
||||||
} else {
|
} else {
|
||||||
workitem.removeItem("steuer.zoll.due");
|
workitem.removeItem("steuer.zoll.due");
|
||||||
}
|
}
|
||||||
InvoiceUtil.implodeChildList(workitem, rows);
|
InvoiceUtil.implodeChildList(workitem, rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aktualisiert den invoice.saldo anhand der ausgehenden Rechnungen zu einer ATC
|
* Aktualisiert den invoice.saldo anhand der ausgehenden Rechnungen zu einer ATC
|
||||||
* Nummer
|
* Nummer
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected void updateInvoiceSaldo(ItemCollection workitem) {
|
protected void updateInvoiceSaldo(ItemCollection workitem) {
|
||||||
|
|
||||||
String atcNummer = workitem.getItemValueString("invoice.atc.number");
|
String atcNummer = workitem.getItemValueString("invoice.atc.number");
|
||||||
logger.fine("Verify ATC-Nr.: " + atcNummer);
|
logger.fine("Verify ATC-Nr.: " + atcNummer);
|
||||||
double amount = workitem.getItemValueDouble("invoice.total.net");
|
double amount = workitem.getItemValueDouble("invoice.total.net");
|
||||||
List<ItemCollection> invoices = findInvoices(atcNummer);
|
List<ItemCollection> invoices = findInvoices(atcNummer);
|
||||||
|
|
||||||
// Beträge subtrahieren....
|
// Beträge subtrahieren....
|
||||||
double saldo = amount;
|
double saldo = amount;
|
||||||
logger.info("Found " + invoices.size() + " matching invoices...");
|
logger.info("Found " + invoices.size() + " matching invoices...");
|
||||||
for (ItemCollection invoice : invoices) {
|
for (ItemCollection invoice : invoices) {
|
||||||
workitem.setItemValueUnique("$workitemRef", invoice.getUniqueID());
|
workitem.setItemValueUnique("$workitemRef", invoice.getUniqueID());
|
||||||
|
|
||||||
// suche die Zeile in der die ATC Nummer vorkommt.
|
// suche die Zeile in der die ATC Nummer vorkommt.
|
||||||
List<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
|
List<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
|
||||||
for (ItemCollection pos : positionen) {
|
for (ItemCollection pos : positionen) {
|
||||||
if (atcNummer.equals(pos.getItemValueString("atc.number"))) {
|
if (atcNummer.equals(pos.getItemValueString("atc.number"))) {
|
||||||
double umsatz = pos.getItemValueDouble("datev.umsatz");
|
double umsatz = pos.getItemValueDouble("datev.umsatz");
|
||||||
logger.info("...Umsatz=" + umsatz);
|
logger.info("...Umsatz=" + umsatz);
|
||||||
saldo = InvoiceUtil.round(saldo - umsatz);
|
saldo = InvoiceUtil.round(saldo - umsatz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Saldo
|
// Update Saldo
|
||||||
workitem.setItemValue("invoice.saldo", InvoiceUtil.round(saldo));
|
workitem.setItemValue("invoice.saldo", InvoiceUtil.round(saldo));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sucht alle Ausgansrechnungen zu einer ATC Nummer
|
* Sucht alle Ausgansrechnungen zu einer ATC Nummer
|
||||||
*/
|
*/
|
||||||
protected List<ItemCollection> findInvoices(String atcNumber) {
|
protected List<ItemCollection> findInvoices(String atcNumber) {
|
||||||
List<ItemCollection> result = new ArrayList<ItemCollection>();
|
List<ItemCollection> result = new ArrayList<ItemCollection>();
|
||||||
String query = "(type:workitem OR type:workitemarchive) AND ($taskid:[5000 TO 5990])"
|
String query = "(type:workitem OR type:workitemarchive) AND ($taskid:[5000 TO 5990])"
|
||||||
+ " AND invoice.atc.number:\"" + atcNumber + "\" "
|
+ " AND invoice.atc.number:\"" + atcNumber + "\" " + " AND $workflowgroup:\"Rechnungsausgang\" ";
|
||||||
+ " AND $workflowgroup:\"Rechnungsausgang\" ";
|
try {
|
||||||
try {
|
result = documentService.find(query, 999, 0, "$created", false);
|
||||||
result = documentService.find(query, 999, 0, "$created", false);
|
return result;
|
||||||
return result;
|
} catch (QueryException e) {
|
||||||
} catch (QueryException e) {
|
logger.severe("Failed to get invoices: " + e.getMessage());
|
||||||
logger.severe("Failed to get invoices: " + e.getMessage());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ import jakarta.inject.Inject;
|
||||||
* Kredito erzeugt der Adapter automatisch eine neue Prozessinstanz.
|
* Kredito erzeugt der Adapter automatisch eine neue Prozessinstanz.
|
||||||
* <p>
|
* <p>
|
||||||
* Wurde die Rechnugn bereits einem Zahlungsavis zugeordnet passiert nichts.
|
* Wurde die Rechnugn bereits einem Zahlungsavis zugeordnet passiert nichts.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -40,7 +40,7 @@ public class ZahlungsavisAppendAdapter implements SignalAdapter {
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Zahlungsavis and adds a reference
|
* This method finds or create the Zahlungsavis and adds a reference
|
||||||
* ($workitemref) to the current invoice.
|
* ($workitemref) to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -54,7 +54,7 @@ public class ZahlungsavisAppendAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese method hängt eine referenz der aktuellen Rechnung an den Zahlungsavis
|
* Diese method hängt eine referenz der aktuellen Rechnung an den Zahlungsavis
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -100,7 +100,7 @@ public class ZahlungsavisAppendAdapter implements SignalAdapter {
|
||||||
/**
|
/**
|
||||||
* Prüft alle offenen Zahlugnsaviss und gibt den neuesten zur angegebenen
|
* Prüft alle offenen Zahlugnsaviss und gibt den neuesten zur angegebenen
|
||||||
* cdrNumber zurück, oder null falls es keinen Offenen Zahlungsavis gibt.
|
* cdrNumber zurück, oder null falls es keinen Offenen Zahlungsavis gibt.
|
||||||
*
|
*
|
||||||
* @param cdrNumber
|
* @param cdrNumber
|
||||||
* @return
|
* @return
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import jakarta.inject.Named;
|
||||||
* <p>
|
* <p>
|
||||||
* Zusätzlich bietet er die Summenberechnung an, bei der die Gutschriften
|
* Zusätzlich bietet er die Summenberechnung an, bei der die Gutschriften
|
||||||
* abgezogen werden.
|
* abgezogen werden.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -41,7 +41,7 @@ public class ZahlungsavisController implements Serializable {
|
||||||
* result is rounded to 2 digits.
|
* result is rounded to 2 digits.
|
||||||
* <p>
|
* <p>
|
||||||
* Gutschriften werden abgezogen
|
* Gutschriften werden abgezogen
|
||||||
*
|
*
|
||||||
* @param refids - list of workitem uniqueIds
|
* @param refids - list of workitem uniqueIds
|
||||||
* @param item - name of the item to summarize
|
* @param item - name of the item to summarize
|
||||||
* @return sum rounded to 2 digits
|
* @return sum rounded to 2 digits
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der ZahlungsavisAdapter importiert eine Excel Datei aus einem Textblock
|
* Der ZahlungsavisAdapter importiert eine Excel Datei aus einem Textblock
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<zahlungsavis name="textblock">textblock-ref</zahlungsavis>
|
<zahlungsavis name="textblock">textblock-ref</zahlungsavis>
|
||||||
|
|
@ -38,7 +38,7 @@ import jakarta.inject.Inject;
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
|
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
|
||||||
* (siehe POIFineReplaceAdapter).
|
* (siehe POIFineReplaceAdapter).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
|
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
|
||||||
* 16 eingefügt werden.
|
* 16 eingefügt werden.
|
||||||
|
|
@ -46,7 +46,7 @@ import jakarta.inject.Inject;
|
||||||
* Dabei werden Gutschriften in spalte E und Rechnungen in Spalte F eingetrgen.
|
* Dabei werden Gutschriften in spalte E und Rechnungen in Spalte F eingetrgen.
|
||||||
* <p>
|
* <p>
|
||||||
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -69,7 +69,7 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Zahlungsavis and adds a reference
|
* This method finds or create the Zahlungsavis and adds a reference
|
||||||
* ($workitemref) to the current invoice.
|
* ($workitemref) to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -121,7 +121,7 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
|
||||||
* <p>
|
* <p>
|
||||||
* The named cell 'TOTAL' should contain the summary formula. It will be
|
* The named cell 'TOTAL' should contain the summary formula. It will be
|
||||||
* evaluated at the end.
|
* evaluated at the end.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -193,7 +193,7 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method loads a text-block for a specified ref and appends the named
|
* This method loads a text-block for a specified ref and appends the named
|
||||||
* fileData object of this document.
|
* fileData object of this document.
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -223,9 +223,9 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a text-block ItemCollection for a specified name.
|
* This method returns a text-block ItemCollection for a specified name.
|
||||||
*
|
*
|
||||||
* @param name in attribute txtname
|
* @param name in attribute txtname
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public FileData loadTextBlockFileData(String name, String fileName) {
|
public FileData loadTextBlockFileData(String name, String fileName) {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import jakarta.inject.Inject;
|
||||||
* <li>payment.amount
|
* <li>payment.amount
|
||||||
* <p>
|
* <p>
|
||||||
* <code>com.alexanderlogistics.ZahlungseingangSaldoAdapter</code>
|
* <code>com.alexanderlogistics.ZahlungseingangSaldoAdapter</code>
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -51,7 +51,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
|
||||||
/**
|
/**
|
||||||
* This method finds the outgoing invoices and updates the saldo
|
* This method finds the outgoing invoices and updates the saldo
|
||||||
* (payment.total).
|
* (payment.total).
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -72,7 +72,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese methode aktuallisiert alle referenzen der aktuellen Rechnungen
|
* Diese methode aktuallisiert alle referenzen der aktuellen Rechnungen
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -127,13 +127,11 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
|
||||||
|
|
||||||
String mainCurrency = invoiceService.getCurrenciesOutMain();
|
String mainCurrency = invoiceService.getCurrenciesOutMain();
|
||||||
if ((!invoiceCurrency.equals(paymentCurrency))
|
if ((!invoiceCurrency.equals(paymentCurrency))
|
||||||
&& (!invoiceCurrency.equals(mainCurrency) &&
|
&& (!invoiceCurrency.equals(mainCurrency) && !paymentCurrency.equals(mainCurrency))) {
|
||||||
!paymentCurrency.equals(mainCurrency))) {
|
|
||||||
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT4");
|
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT4");
|
||||||
message = message.replace("{1}", mainCurrency);
|
message = message.replace("{1}", mainCurrency);
|
||||||
throw new PluginException(PluginException.class.getName(),
|
throw new PluginException(PluginException.class.getName(),
|
||||||
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED,
|
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
|
||||||
message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!invoiceCurrency.equals(paymentCurrency)) {
|
if (!invoiceCurrency.equals(paymentCurrency)) {
|
||||||
|
|
@ -142,8 +140,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
|
||||||
message = message.replace("{1}", paymentCurrency);
|
message = message.replace("{1}", paymentCurrency);
|
||||||
message = message.replace("{2}", invoiceNumber);
|
message = message.replace("{2}", invoiceNumber);
|
||||||
throw new PluginException(PluginException.class.getName(),
|
throw new PluginException(PluginException.class.getName(),
|
||||||
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED,
|
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
|
||||||
message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,8 +148,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
|
||||||
* Falls die Währung der Rechnung von der Währung der Zahlung abweicht, dann
|
* Falls die Währung der Rechnung von der Währung der Zahlung abweicht, dann
|
||||||
* rechnen wir den PaymentAmmout mit der Rate aus.
|
* rechnen wir den PaymentAmmout mit der Rate aus.
|
||||||
*/
|
*/
|
||||||
if ("EUR".equals(paymentCurrency) &&
|
if ("EUR".equals(paymentCurrency) && !invoiceCurrency.equals(paymentCurrency) && invoiceRate != 0) {
|
||||||
!invoiceCurrency.equals(paymentCurrency) && invoiceRate != 0) {
|
|
||||||
invoicePaymentAmount = invoicePaymentAmount * invoiceRate;
|
invoicePaymentAmount = invoicePaymentAmount * invoiceRate;
|
||||||
// runde auf 2 Stellen
|
// runde auf 2 Stellen
|
||||||
invoicePaymentAmount = (float) InvoiceUtil.round(invoicePaymentAmount);
|
invoicePaymentAmount = (float) InvoiceUtil.round(invoicePaymentAmount);
|
||||||
|
|
@ -213,7 +209,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true wenn der Zahlungseingang bereits gebucht ist
|
* Returns true wenn der Zahlungseingang bereits gebucht ist
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow
|
* Imixs Workflow
|
||||||
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* http://www.imixs.org
|
* http://www.imixs.org
|
||||||
* http://java.net/projects/imixs-workflow
|
* http://java.net/projects/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -49,9 +49,9 @@ import jakarta.inject.Inject;
|
||||||
/**
|
/**
|
||||||
* Der ZahlungseingangService wird vom ZahlungseingangSaldoAdapter verwendet um
|
* Der ZahlungseingangService wird vom ZahlungseingangSaldoAdapter verwendet um
|
||||||
* Ausgangsrechnungen zu akutalisieren.
|
* Ausgangsrechnungen zu akutalisieren.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||||
|
|
@ -79,7 +79,7 @@ public class ZahlungseingangService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Method sucht eine Invoice mit Manager Rechnten
|
* Diese Method sucht eine Invoice mit Manager Rechnten
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
public ItemCollection findInvoice(String id) throws PluginException {
|
public ItemCollection findInvoice(String id) throws PluginException {
|
||||||
|
|
@ -89,7 +89,7 @@ public class ZahlungseingangService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * Diese Method processed eine Invoice mit Manager Rechnten
|
* * Diese Method processed eine Invoice mit Manager Rechnten
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws ModelException
|
* @throws ModelException
|
||||||
* @throws ProcessingErrorException
|
* @throws ProcessingErrorException
|
||||||
|
|
@ -106,10 +106,10 @@ public class ZahlungseingangService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The method returns a List of ItemCollection holding the payment details
|
* The method returns a List of ItemCollection holding the payment details
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Convert the List of ItemCollections back into a List of Map elements
|
* Convert the List of ItemCollections back into a List of Map elements
|
||||||
*
|
*
|
||||||
* @param invoice
|
* @param invoice
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
|
|
||||||
|
|
@ -15,23 +15,23 @@ import jakarta.enterprise.event.Observes;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The PromptExampleAdapterXML is a CDI bean that creates XML examples based
|
* The PromptExampleAdapterXML is a CDI bean that creates XML examples based on
|
||||||
* on the last 3 invoices.
|
* the last 3 invoices.
|
||||||
*
|
*
|
||||||
* The adapter only runs if the prompt template contains
|
* The adapter only runs if the prompt template contains
|
||||||
*
|
*
|
||||||
* <<EXAMPLES_XML>>
|
* <<EXAMPLES_XML>>
|
||||||
*
|
*
|
||||||
* Prompt example generated by this Adapter:
|
* Prompt example generated by this Adapter:
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
* 1. Company Data:
|
* 1. Company Data:
|
||||||
* - Name and address of the supplier
|
* - Name and address of the supplier
|
||||||
* - Supplier contact information (phone number, email, etc.)
|
* - Supplier contact information (phone number, email, etc.)
|
||||||
*
|
*
|
||||||
* 2. Invoice Data:
|
* 2. Invoice Data:
|
||||||
* - Invoice number
|
* - Invoice number
|
||||||
* - Invoice date
|
* - Invoice date
|
||||||
|
|
@ -41,7 +41,7 @@ import jakarta.inject.Inject;
|
||||||
*
|
*
|
||||||
* <invoice>
|
* <invoice>
|
||||||
* <cdtr.name>...</cdtr.name>
|
* <cdtr.name>...</cdtr.name>
|
||||||
* <invoice.number>...</invoice.number>
|
* <invoice.number>...</invoice.number>
|
||||||
* <invoice.date>2024-12-31</invoice.date>
|
* <invoice.date>2024-12-31</invoice.date>
|
||||||
* <invoice.duedate>2024-12-31</invoice.duedate>
|
* <invoice.duedate>2024-12-31</invoice.duedate>
|
||||||
* <invoice.total type="double">1234.00</invoice.total>
|
* <invoice.total type="double">1234.00</invoice.total>
|
||||||
|
|
@ -50,7 +50,7 @@ import jakarta.inject.Inject;
|
||||||
* </invoice>
|
* </invoice>
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PromptExampleAdapterXML {
|
public class PromptExampleAdapterXML {
|
||||||
private static Logger logger = Logger.getLogger(PromptExampleAdapterXML.class.getName());
|
private static Logger logger = Logger.getLogger(PromptExampleAdapterXML.class.getName());
|
||||||
|
|
@ -79,8 +79,7 @@ public class PromptExampleAdapterXML {
|
||||||
if (invoices != null && invoices.size() > 0) {
|
if (invoices != null && invoices.size() > 0) {
|
||||||
// Build an example for each invoice
|
// Build an example for each invoice
|
||||||
for (ItemCollection invoice : invoices) {
|
for (ItemCollection invoice : invoices) {
|
||||||
promptExamples = promptExamples + buildExampleDE(invoice, exampleHeaderData,
|
promptExamples = promptExamples + buildExampleDE(invoice, exampleHeaderData, exampleHeaderXML);
|
||||||
exampleHeaderXML);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prompt = prompt.replace("<<EXAMPLES_XML>>", "" + promptExamples);
|
prompt = prompt.replace("<<EXAMPLES_XML>>", "" + promptExamples);
|
||||||
|
|
@ -91,13 +90,13 @@ public class PromptExampleAdapterXML {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper Method that builds a prompt example out of an existing invoice:
|
* Helper Method that builds a prompt example out of an existing invoice:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
*
|
*
|
||||||
* <invoice>
|
* <invoice>
|
||||||
* <cdtr.name>...</cdtr.name>
|
* <cdtr.name>...</cdtr.name>
|
||||||
* <invoice.number>...</invoice.number>
|
* <invoice.number>...</invoice.number>
|
||||||
* <invoice.date>2024-12-31</invoice.date>
|
* <invoice.date>2024-12-31</invoice.date>
|
||||||
* <invoice.duedate>2024-12-31</invoice.duedate>
|
* <invoice.duedate>2024-12-31</invoice.duedate>
|
||||||
* <invoice.total type="double">1234.00</invoice.total>
|
* <invoice.total type="double">1234.00</invoice.total>
|
||||||
|
|
@ -106,7 +105,7 @@ public class PromptExampleAdapterXML {
|
||||||
* </invoice>
|
* </invoice>
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param invoice
|
* @param invoice
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -126,14 +125,12 @@ public class PromptExampleAdapterXML {
|
||||||
example.append(
|
example.append(
|
||||||
" <invoice.number>" + invoice.getItemValueString("invoice.number") + "</invoice.number>\n");
|
" <invoice.number>" + invoice.getItemValueString("invoice.number") + "</invoice.number>\n");
|
||||||
if (invoice.getItemValueDate("invoice.date") != null) {
|
if (invoice.getItemValueDate("invoice.date") != null) {
|
||||||
example.append(
|
example.append(" <invoice.date>" + dateFormat.format(invoice.getItemValueDate("invoice.date"))
|
||||||
" <invoice.date>" + dateFormat.format(invoice.getItemValueDate("invoice.date"))
|
+ "</invoice.date>\n");
|
||||||
+ "</invoice.date>\n");
|
|
||||||
}
|
}
|
||||||
if (invoice.getItemValueDate("invoice.duedate") != null) {
|
if (invoice.getItemValueDate("invoice.duedate") != null) {
|
||||||
example.append(
|
example.append(" <invoice.duedate>" + dateFormat.format(invoice.getItemValueDate("invoice.duedate"))
|
||||||
" <invoice.duedate>" + dateFormat.format(invoice.getItemValueDate("invoice.duedate"))
|
+ "</invoice.duedate>\n");
|
||||||
+ "</invoice.duedate>\n");
|
|
||||||
}
|
}
|
||||||
example.append(" <invoice.total type=\"double\">" + invoice.getItemValueDouble("invoice.total")
|
example.append(" <invoice.total type=\"double\">" + invoice.getItemValueDouble("invoice.total")
|
||||||
+ "</invoice.total>\n");
|
+ "</invoice.total>\n");
|
||||||
|
|
@ -146,7 +143,7 @@ public class PromptExampleAdapterXML {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to find the last 3 invoices by cdtr.name
|
* Helper method to find the last 3 invoices by cdtr.name
|
||||||
*
|
*
|
||||||
* @param cdtrName
|
* @param cdtrName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -154,8 +151,7 @@ public class PromptExampleAdapterXML {
|
||||||
List<ItemCollection> result = new ArrayList<>();
|
List<ItemCollection> result = new ArrayList<>();
|
||||||
|
|
||||||
String searchTerm = "(type:workitemarchive) AND ($modelversion:rechnungseingang*) AND ($taskid:5900) AND NOT ($uniqueid:"
|
String searchTerm = "(type:workitemarchive) AND ($modelversion:rechnungseingang*) AND ($taskid:5900) AND NOT ($uniqueid:"
|
||||||
+ currentID + ") AND (document.company:\""
|
+ currentID + ") AND (document.company:\"" + companyName + "\")";
|
||||||
+ companyName + "\")";
|
|
||||||
try {
|
try {
|
||||||
result = documentService.find(searchTerm, 3, 0, "$modified", true);
|
result = documentService.find(searchTerm, 3, 0, "$modified", true);
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow
|
* Imixs Workflow
|
||||||
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* http://www.imixs.org
|
* http://www.imixs.org
|
||||||
* http://java.net/projects/imixs-workflow
|
* http://java.net/projects/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -60,9 +60,9 @@ import jakarta.ws.rs.core.MediaType;
|
||||||
/**
|
/**
|
||||||
** Dieser Service korrigiert falsch importierte Cargosoft daten.
|
** Dieser Service korrigiert falsch importierte Cargosoft daten.
|
||||||
* Ausgangsrechnungen die ein falsches Jahr haben.
|
* Ausgangsrechnungen die ein falsches Jahr haben.
|
||||||
*
|
*
|
||||||
* Oder DAten die über die XML Schnittstelle falsch reinkamen...
|
* Oder DAten die über die XML Schnittstelle falsch reinkamen...
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.1
|
* @version 1.1
|
||||||
*/
|
*/
|
||||||
|
|
@ -109,12 +109,12 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
* Dieser agent speichert einfach alle Cargosoft Krediotren/Debitoren Daten ,
|
* Dieser agent speichert einfach alle Cargosoft Krediotren/Debitoren Daten ,
|
||||||
* was dann zur automatischen Neuanlage bzw. aktualisierung des businesspartner
|
* was dann zur automatischen Neuanlage bzw. aktualisierung des businesspartner
|
||||||
* workflows führt.
|
* workflows führt.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* curl -H "Cookie:
|
* curl -H "Cookie:
|
||||||
* JSESSIONID=ShAegfNiXmqLFLSFwcUZ7hrLLQDKZGKiu4oj_xeX.imixs-office-workflow-8586d7d58d-h6k4q"
|
* JSESSIONID=ShAegfNiXmqLFLSFwcUZ7hrLLQDKZGKiu4oj_xeX.imixs-office-workflow-8586d7d58d-h6k4q"
|
||||||
* https://alexander-logistics-dwc.office-workflow.de/api/cargosoft/bp-sync?maxcount=1000
|
* https://alexander-logistics-dwc.office-workflow.de/api/cargosoft/bp-sync?maxcount=1000
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
|
|
@ -145,8 +145,7 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
|
|
||||||
int totalCount = documentService.count(query);
|
int totalCount = documentService.count(query);
|
||||||
log("│ ├── found " + totalCount + " cargosoft entries",
|
log("│ ├── found " + totalCount + " cargosoft entries", messageBuffer);
|
||||||
messageBuffer);
|
|
||||||
|
|
||||||
// Berechne Anzahl der benötigten Pages
|
// Berechne Anzahl der benötigten Pages
|
||||||
int totalPages = (int) Math.ceil((double) totalCount / batchSize);
|
int totalPages = (int) Math.ceil((double) totalCount / batchSize);
|
||||||
|
|
@ -169,8 +168,8 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fortschritt loggen
|
// Fortschritt loggen
|
||||||
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages +
|
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages + " (" + totalObjects
|
||||||
" (" + totalObjects + " objects read, " + syncs + " total syncs)", messageBuffer);
|
+ " objects read, " + syncs + " total syncs)", messageBuffer);
|
||||||
// Optional: Kurze Pause nach jedem 5. Batch
|
// Optional: Kurze Pause nach jedem 5. Batch
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|
@ -185,8 +184,8 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
}
|
}
|
||||||
long duration = System.currentTimeMillis() - l;
|
long duration = System.currentTimeMillis() - l;
|
||||||
double objectsPerSecond = totalObjects / (duration / 1000.0);
|
double objectsPerSecond = totalObjects / (duration / 1000.0);
|
||||||
log("├── Successfully " + syncs + " business partner objects synced in " +
|
log("├── Successfully " + syncs + " business partner objects synced in " + duration + "ms ("
|
||||||
duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
|
+ String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
|
||||||
|
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
return messageBuffer.toString();
|
return messageBuffer.toString();
|
||||||
|
|
@ -194,7 +193,7 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode speichert eine cargoosft kreditor object...
|
* Hilfsmethode speichert eine cargoosft kreditor object...
|
||||||
*
|
*
|
||||||
* @param bpID
|
* @param bpID
|
||||||
* @param messageBuffer
|
* @param messageBuffer
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -213,11 +212,11 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Dieser agent löscht einfach alle Businesspartner objekte. Wird eigentlich
|
* Dieser agent löscht einfach alle Businesspartner objekte. Wird eigentlich
|
||||||
* nicht mehr benötigt.
|
* nicht mehr benötigt.
|
||||||
*
|
*
|
||||||
* curl -H "Cookie:
|
* curl -H "Cookie:
|
||||||
* JSESSIONID=ShAegfNiXmqLFLSFwcUZ7hrLLQDKZGKiu4oj_xeX.imixs-office-workflow-8586d7d58d-h6k4q"
|
* JSESSIONID=ShAegfNiXmqLFLSFwcUZ7hrLLQDKZGKiu4oj_xeX.imixs-office-workflow-8586d7d58d-h6k4q"
|
||||||
* https://alexander-logistics-dwc.office-workflow.de/api/cargosoft/bp-delete?maxcount=10000
|
* https://alexander-logistics-dwc.office-workflow.de/api/cargosoft/bp-delete?maxcount=10000
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
|
|
@ -273,8 +272,8 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
|
|
||||||
// Fortschritt loggen
|
// Fortschritt loggen
|
||||||
iterations++;
|
iterations++;
|
||||||
log("│ ├── Processed page " + (iterations) + " of " + totalPages +
|
log("│ ├── Processed page " + (iterations) + " of " + totalPages + " (" + deletions + " total deletions)",
|
||||||
" (" + deletions + " total deletions)", messageBuffer);
|
messageBuffer);
|
||||||
|
|
||||||
// Optional: Kurze Pause nach jedem 5. Batch
|
// Optional: Kurze Pause nach jedem 5. Batch
|
||||||
try {
|
try {
|
||||||
|
|
@ -290,8 +289,8 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
}
|
}
|
||||||
long duration = System.currentTimeMillis() - l;
|
long duration = System.currentTimeMillis() - l;
|
||||||
double objectsPerSecond = totalObjects / (duration / 1000.0);
|
double objectsPerSecond = totalObjects / (duration / 1000.0);
|
||||||
log("├── Successfully " + deletions + " business partner objects deleted in " +
|
log("├── Successfully " + deletions + " business partner objects deleted in " + duration + "ms ("
|
||||||
duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
|
+ String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
|
||||||
|
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
return messageBuffer.toString();
|
return messageBuffer.toString();
|
||||||
|
|
@ -299,7 +298,7 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entfernt doppelte Eintrage - sind irgnedwie entstandnen :(((
|
* Entfernt doppelte Eintrage - sind irgnedwie entstandnen :(((
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
|
|
@ -373,8 +372,8 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
|
|
||||||
// Fortschritt loggen
|
// Fortschritt loggen
|
||||||
// Fortschritt loggen
|
// Fortschritt loggen
|
||||||
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages +
|
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages + " (" + deletions
|
||||||
" (" + deletions + " total deletions)", messageBuffer);
|
+ " total deletions)", messageBuffer);
|
||||||
// Optional: Kurze Pause nach jedem 5. Batch
|
// Optional: Kurze Pause nach jedem 5. Batch
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|
@ -389,8 +388,8 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
}
|
}
|
||||||
long duration = System.currentTimeMillis() - l;
|
long duration = System.currentTimeMillis() - l;
|
||||||
double objectsPerSecond = totalObjects / (duration / 1000.0);
|
double objectsPerSecond = totalObjects / (duration / 1000.0);
|
||||||
log("├── Successfully " + deletions + " duplicated cargosoft objects deleted in " +
|
log("├── Successfully " + deletions + " duplicated cargosoft objects deleted in " + duration + "ms ("
|
||||||
duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
|
+ String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
|
||||||
|
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
return messageBuffer.toString();
|
return messageBuffer.toString();
|
||||||
|
|
@ -398,7 +397,7 @@ public class CargosoftMigrationRestService implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode - löscht ein cargoosoft object...
|
* Hilfsmethode - löscht ein cargoosoft object...
|
||||||
*
|
*
|
||||||
* @param bpID
|
* @param bpID
|
||||||
* @param messageBuffer
|
* @param messageBuffer
|
||||||
* @return
|
* @return
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
/*
|
/*
|
||||||
* Imixs-Workflow
|
* Imixs-Workflow
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* https://www.imixs.org
|
* https://www.imixs.org
|
||||||
* https://github.com/imixs/imixs-workflow
|
* https://github.com/imixs/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - Project Management
|
* Imixs Software Solutions GmbH - Project Management
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*/
|
*/
|
||||||
|
|
@ -58,7 +58,7 @@ import jakarta.ws.rs.core.Response;
|
||||||
/**
|
/**
|
||||||
* The api endpoint '/data' provides methods to read and post data via a access
|
* The api endpoint '/data' provides methods to read and post data via a access
|
||||||
* token
|
* token
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
|
|
@ -87,7 +87,7 @@ public class DataRestService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method
|
* Test method
|
||||||
*
|
*
|
||||||
* @param workflowgroup
|
* @param workflowgroup
|
||||||
* @param task
|
* @param task
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -132,16 +132,14 @@ public class DataRestService {
|
||||||
* this token to the service.
|
* this token to the service.
|
||||||
* <p>
|
* <p>
|
||||||
* The method tests the access. If it is not possible the method returns null.
|
* The method tests the access. If it is not possible the method returns null.
|
||||||
*
|
*
|
||||||
* @see DefaultAuthenicator
|
* @see DefaultAuthenicator
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected Client createClient(String serviceAPI, String sessionID) {
|
protected Client createClient(String serviceAPI, String sessionID) {
|
||||||
|
|
||||||
// Create a Cookie object with a name and a value
|
// Create a Cookie object with a name and a value
|
||||||
Cookie cookie = new Cookie.Builder("JSESSIONID")
|
Cookie cookie = new Cookie.Builder("JSESSIONID").value(sessionID).path("/")
|
||||||
.value(sessionID)
|
|
||||||
.path("/")
|
|
||||||
// .domain("domain.com")
|
// .domain("domain.com")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
@ -173,7 +171,7 @@ public class DataRestService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches a report by name
|
* Searches a report by name
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* @return
|
* @return
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,26 @@ package com.alexanderlogistics.datev;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
@ -39,43 +39,43 @@ import jakarta.inject.Named;
|
||||||
* txtname=datev".
|
* txtname=datev".
|
||||||
* <p>
|
* <p>
|
||||||
* The following config items are defined:
|
* The following config items are defined:
|
||||||
*
|
*
|
||||||
* The following config items are defined:
|
* The following config items are defined:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* _model_version = model version for the SEPA export
|
* _model_version = model version for the SEPA export
|
||||||
* _initial_task = inital task ID
|
* _initial_task = inital task ID
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Named
|
@Named
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class CargosoftExportController extends SchedulerController {
|
public class CargosoftExportController extends SchedulerController {
|
||||||
|
|
||||||
public static final String CARGOSOFT_EXPORT_CONFIGURATION = "CARGOSOFT_EXPORT_CONFIGURATION";
|
public static final String CARGOSOFT_EXPORT_CONFIGURATION = "CARGOSOFT_EXPORT_CONFIGURATION";
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(CargosoftExportController.class.getName());
|
private static Logger logger = Logger.getLogger(CargosoftExportController.class.getName());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return CARGOSOFT_EXPORT_CONFIGURATION;
|
return CARGOSOFT_EXPORT_CONFIGURATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sepa scheduler class name. This name depends on the _export_type.
|
* Returns the sepa scheduler class name. This name depends on the _export_type.
|
||||||
*
|
*
|
||||||
* There are two export interfaces available - csv and XML
|
* There are two export interfaces available - csv and XML
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getSchedulerClass() {
|
public String getSchedulerClass() {
|
||||||
String schedulerClass = CargosoftExportScheduler.class.getName();
|
String schedulerClass = CargosoftExportScheduler.class.getName();
|
||||||
logger.finest("...... scheduler: " + schedulerClass);
|
logger.finest("...... scheduler: " + schedulerClass);
|
||||||
return schedulerClass;
|
return schedulerClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -61,10 +61,10 @@ import jakarta.ejb.EJB;
|
||||||
* The class implements the interface
|
* The class implements the interface
|
||||||
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
|
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
|
||||||
* combination with the Imxis-Workflow Scheduler Service.
|
* combination with the Imxis-Workflow Scheduler Service.
|
||||||
*
|
*
|
||||||
* @see SchedulerService
|
* @see SchedulerService
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CargosoftExportScheduler implements Scheduler {
|
public class CargosoftExportScheduler implements Scheduler {
|
||||||
|
|
||||||
|
|
@ -94,9 +94,9 @@ public class CargosoftExportScheduler implements Scheduler {
|
||||||
/**
|
/**
|
||||||
* This is the method which processes the timeout event depending on the running
|
* This is the method which processes the timeout event depending on the running
|
||||||
* timer settings.
|
* timer settings.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param timer
|
* @param timer
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*/
|
*/
|
||||||
|
|
@ -198,7 +198,7 @@ public class CargosoftExportScheduler implements Scheduler {
|
||||||
/**
|
/**
|
||||||
* Diese Hilfsmehtode überträgt eine Datei an einen FTP Server. Die
|
* Diese Hilfsmehtode überträgt eine Datei an einen FTP Server. Die
|
||||||
* Verbindugnsdaten stehen im Configuraiton Workitem.
|
* Verbindugnsdaten stehen im Configuraiton Workitem.
|
||||||
*
|
*
|
||||||
* @param fileData object
|
* @param fileData object
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ import jakarta.inject.Named;
|
||||||
/**
|
/**
|
||||||
* Der ExcelExportController exportiert rechnungen anhand von Filterangaben
|
* Der ExcelExportController exportiert rechnungen anhand von Filterangaben
|
||||||
* (excel_export_rechnungsausgang.xhmlt) nach Excel.
|
* (excel_export_rechnungsausgang.xhmlt) nach Excel.
|
||||||
*
|
*
|
||||||
* Die Ausgabe ist auf maximal 3000 Zeilen eingeschränkt
|
* Die Ausgabe ist auf maximal 3000 Zeilen eingeschränkt
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -54,291 +54,290 @@ import jakarta.inject.Named;
|
||||||
@ConversationScoped
|
@ConversationScoped
|
||||||
public class ExcelExportController implements Serializable {
|
public class ExcelExportController implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(ExcelExportController.class.getName());
|
private static Logger logger = Logger.getLogger(ExcelExportController.class.getName());
|
||||||
|
|
||||||
public static final String ERROR_CONFIG = "CONFIG_ERROR";
|
public static final String ERROR_CONFIG = "CONFIG_ERROR";
|
||||||
final String TYPE_TEXTBLOCK = "textblock";
|
final String TYPE_TEXTBLOCK = "textblock";
|
||||||
|
|
||||||
public static final int MAX_ROWS = 3000;
|
public static final int MAX_ROWS = 3000;
|
||||||
@Inject
|
@Inject
|
||||||
protected DocumentService documentService;
|
protected DocumentService documentService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
WorkflowController workflowController;
|
WorkflowController workflowController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DocumentController documentController;
|
DocumentController documentController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SnapshotService snapshotService;
|
SnapshotService snapshotService;
|
||||||
|
|
||||||
private ItemCollection filter;
|
private ItemCollection filter;
|
||||||
private CustomFormItem dbtrItem;
|
private CustomFormItem dbtrItem;
|
||||||
|
|
||||||
public ExcelExportController() {
|
public ExcelExportController() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemCollection getFilter() {
|
public ItemCollection getFilter() {
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilter(ItemCollection filter) {
|
public void setFilter(ItemCollection filter) {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
|
* Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
public String export() throws PluginException {
|
public String export() throws PluginException {
|
||||||
|
|
||||||
logger.info("start export....");
|
logger.info("start export....");
|
||||||
Date start = filter.getItemValueDate("start");
|
Date start = filter.getItemValueDate("start");
|
||||||
Date stop = filter.getItemValueDate("stop");
|
Date stop = filter.getItemValueDate("stop");
|
||||||
logger.info("...daterange=" + start + " - " + stop);
|
logger.info("...daterange=" + start + " - " + stop);
|
||||||
|
|
||||||
// serach date range?
|
// serach date range?
|
||||||
String sDateFrom = "191401070000"; // because * did not work here
|
String sDateFrom = "191401070000"; // because * did not work here
|
||||||
String sDateTo = "211401070000";
|
String sDateTo = "211401070000";
|
||||||
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
|
||||||
|
|
||||||
if (start != null) {
|
if (start != null) {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTime(start);
|
cal.setTime(start);
|
||||||
sDateFrom = dateformat.format(cal.getTime());
|
sDateFrom = dateformat.format(cal.getTime());
|
||||||
}
|
}
|
||||||
if (stop != null) {
|
if (stop != null) {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTime(stop);
|
cal.setTime(stop);
|
||||||
cal.add(Calendar.DATE, 1);
|
cal.add(Calendar.DATE, 1);
|
||||||
sDateTo = dateformat.format(cal.getTime());
|
sDateTo = dateformat.format(cal.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
// query zeit
|
// query zeit
|
||||||
String query = "(type:workitem OR type:workitemarchive) AND ($workflowgroup:Rechnungsausgang) ";
|
String query = "(type:workitem OR type:workitemarchive) AND ($workflowgroup:Rechnungsausgang) ";
|
||||||
if (start != null && stop != null) {
|
if (start != null && stop != null) {
|
||||||
query += "AND (invoice.date:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
query += "AND (invoice.date:[" + sDateFrom + " TO " + sDateTo + "]) ";
|
||||||
} else {
|
} else {
|
||||||
throw new PluginException("ERROR", "Bitte geben Sie einen Zeitraum an", null);
|
throw new PluginException("ERROR", "Bitte geben Sie einen Zeitraum an", null);
|
||||||
}
|
}
|
||||||
logger.info(query);
|
logger.info(query);
|
||||||
|
|
||||||
// query Sachprüfung
|
// query Sachprüfung
|
||||||
|
|
||||||
if (!filter.getItemValueString("space.ref").isEmpty()
|
if (!filter.getItemValueString("space.ref").isEmpty() && !"-".equals(filter.getItemValueString("space.ref"))) {
|
||||||
&& !"-".equals(filter.getItemValueString("space.ref"))) {
|
query += " AND ($uniqueidref:" + filter.getItemValueString("space.ref") + ")";
|
||||||
query += " AND ($uniqueidref:" + filter.getItemValueString("space.ref") + ")";
|
}
|
||||||
}
|
if (workflowController.getWorkitem() != null
|
||||||
if (workflowController.getWorkitem() != null
|
&& !workflowController.getWorkitem().getItemValueString("dbtr.number").isEmpty()) {
|
||||||
&& !workflowController.getWorkitem().getItemValueString("dbtr.number").isEmpty()) {
|
query += " AND (dbtr.number:" + workflowController.getWorkitem().getItemValueString("dbtr.number") + ")";
|
||||||
query += " AND (dbtr.number:" + workflowController.getWorkitem().getItemValueString("dbtr.number") + ")";
|
}
|
||||||
}
|
if (!filter.getItemValueString("invoice.text").isEmpty()) {
|
||||||
if (!filter.getItemValueString("invoice.text").isEmpty()) {
|
query += " AND (invoice.positions:" + filter.getItemValueString("invoice.text") + ")";
|
||||||
query += " AND (invoice.positions:" + filter.getItemValueString("invoice.text") + ")";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// load the text block
|
// load the text block
|
||||||
String template = "ausgangsrechnungen-export_template.xlsx";
|
String template = "ausgangsrechnungen-export_template.xlsx";
|
||||||
FileData fileData = loadTextBlockFileData("Excel-Export Template", template);
|
FileData fileData = loadTextBlockFileData("Excel-Export Template", template);
|
||||||
|
|
||||||
// do we found the document?
|
// do we found the document?
|
||||||
if (fileData == null) {
|
if (fileData == null) {
|
||||||
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
||||||
"Missing Excel Export Template - template=" + template + " not found!");
|
"Missing Excel Export Template - template=" + template + " not found!");
|
||||||
}
|
}
|
||||||
String targetName = "ausgangsrechnungen-export_" + dateformat.format(new Date()) + ".xlsx";
|
String targetName = "ausgangsrechnungen-export_" + dateformat.format(new Date()) + ".xlsx";
|
||||||
try {
|
try {
|
||||||
List<ItemCollection> invoices = documentService.find(query, MAX_ROWS, 0, "invoice.date", true);
|
List<ItemCollection> invoices = documentService.find(query, MAX_ROWS, 0, "invoice.date", true);
|
||||||
if (invoices.size() > 0) {
|
if (invoices.size() > 0) {
|
||||||
insertInvoiceRows(invoices, fileData);
|
insertInvoiceRows(invoices, fileData);
|
||||||
}
|
}
|
||||||
fileData.setName(targetName);
|
fileData.setName(targetName);
|
||||||
|
|
||||||
// See:
|
// See:
|
||||||
// https://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean
|
// https://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean
|
||||||
download(fileData);
|
download(fileData);
|
||||||
} catch (IOException | QueryException e) {
|
} catch (IOException | QueryException e) {
|
||||||
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
||||||
"Failed to generate Excel Export: " + e.getMessage());
|
"Failed to generate Excel Export: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Query=" + query);
|
logger.info("Query=" + query);
|
||||||
return "/pages/admin/excel_export_rechnungsausgang.jsf?faces-redirect=true";
|
return "/pages/admin/excel_export_rechnungsausgang.jsf?faces-redirect=true";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to initialize a download
|
* Helper method to initialize a download
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void download(FileData fileData) throws IOException {
|
public void download(FileData fileData) throws IOException {
|
||||||
|
|
||||||
FacesContext facesContext = FacesContext.getCurrentInstance();
|
FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||||
ExternalContext externalContext = facesContext.getExternalContext();
|
ExternalContext externalContext = facesContext.getExternalContext();
|
||||||
|
|
||||||
externalContext.responseReset();
|
externalContext.responseReset();
|
||||||
externalContext.setResponseContentType("application/vnd.ms-excel");
|
externalContext.setResponseContentType("application/vnd.ms-excel");
|
||||||
externalContext.setResponseContentLength(fileData.getContent().length);
|
externalContext.setResponseContentLength(fileData.getContent().length);
|
||||||
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileData.getName() + "\"");
|
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileData.getName() + "\"");
|
||||||
|
|
||||||
OutputStream output = externalContext.getResponseOutputStream();
|
OutputStream output = externalContext.getResponseOutputStream();
|
||||||
|
|
||||||
// Now you can write the InputStream of the file to the above OutputStream the
|
// Now you can write the InputStream of the file to the above OutputStream the
|
||||||
// usual way.
|
// usual way.
|
||||||
output.write(fileData.getContent());
|
output.write(fileData.getContent());
|
||||||
|
|
||||||
facesContext.responseComplete(); // Important! Otherwise Faces will attempt to render the response which
|
facesContext.responseComplete(); // Important! Otherwise Faces will attempt to render the response which
|
||||||
// obviously will fail since it's already written with a file and closed.
|
// obviously will fail since it's already written with a file and closed.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a text-block ItemCollection for a specified name.
|
* This method returns a text-block ItemCollection for a specified name.
|
||||||
*
|
*
|
||||||
* @param name in attribute txtname
|
* @param name in attribute txtname
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private FileData loadTextBlockFileData(String name, String fileName) {
|
private FileData loadTextBlockFileData(String name, String fileName) {
|
||||||
ItemCollection textBlockItemCollection = null;
|
ItemCollection textBlockItemCollection = null;
|
||||||
|
|
||||||
// load text-block by name....
|
// load text-block by name....
|
||||||
String sQuery = "(type:\"" + TYPE_TEXTBLOCK + "\" AND txtname:\"" + name + "\")";
|
String sQuery = "(type:\"" + TYPE_TEXTBLOCK + "\" AND txtname:\"" + name + "\")";
|
||||||
Collection<ItemCollection> col;
|
Collection<ItemCollection> col;
|
||||||
try {
|
try {
|
||||||
// find the textblock...
|
// find the textblock...
|
||||||
col = documentService.find(sQuery, 1, 0);
|
col = documentService.find(sQuery, 1, 0);
|
||||||
if (col.size() > 0) {
|
if (col.size() > 0) {
|
||||||
textBlockItemCollection = col.iterator().next();
|
textBlockItemCollection = col.iterator().next();
|
||||||
// fetch the fileData...
|
// fetch the fileData...
|
||||||
return snapshotService.getWorkItemFile(textBlockItemCollection.getUniqueID(), fileName);
|
return snapshotService.getWorkItemFile(textBlockItemCollection.getUniqueID(), fileName);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logger.warning("Missing text-block : '" + name + "'");
|
logger.warning("Missing text-block : '" + name + "'");
|
||||||
}
|
}
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
logger.warning("getTextBlock - invalid query: " + e.getMessage());
|
logger.warning("getTextBlock - invalid query: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method reset the search and input state.
|
* This method reset the search and input state.
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
filter = new ItemCollection();
|
filter = new ItemCollection();
|
||||||
|
|
||||||
// compute start stop based on current month
|
// compute start stop based on current month
|
||||||
YearMonth startYearMonth = YearMonth.now();
|
YearMonth startYearMonth = YearMonth.now();
|
||||||
java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
|
java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
|
||||||
java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
|
java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
|
||||||
filter.setItemValue("start",
|
filter.setItemValue("start",
|
||||||
java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
filter.setItemValue("stop",
|
filter.setItemValue("stop",
|
||||||
java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
workflowController.setWorkitem(new ItemCollection());
|
workflowController.setWorkitem(new ItemCollection());
|
||||||
|
|
||||||
// debtr item
|
// debtr item
|
||||||
dbtrItem = new CustomFormItem("dbtr.number", "text", "", false, false, false, "", null, false, 0);
|
dbtrItem = new CustomFormItem("dbtr.number", "text", "", false, false, false, "", null, false, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomFormItem getItem() {
|
public CustomFormItem getItem() {
|
||||||
// dbtrItem.setName("dbtr.number");
|
// dbtrItem.setName("dbtr.number");
|
||||||
return dbtrItem;
|
return dbtrItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper method inserts a row for each invoice
|
* This helper method inserts a row for each invoice
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private void insertInvoiceRows(List<ItemCollection> invoices, FileData fileData) throws PluginException {
|
private void insertInvoiceRows(List<ItemCollection> invoices, FileData fileData) throws PluginException {
|
||||||
// load XSSFWorkbook
|
// load XSSFWorkbook
|
||||||
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
|
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
|
||||||
XSSFWorkbook doc = new XSSFWorkbook(imputStream);
|
XSSFWorkbook doc = new XSSFWorkbook(imputStream);
|
||||||
// NOTE: we only take the first sheet !
|
// NOTE: we only take the first sheet !
|
||||||
XSSFSheet sheet = doc.getSheetAt(0);
|
XSSFSheet sheet = doc.getSheetAt(0);
|
||||||
|
|
||||||
XSSFCell standCell = getCellByRef(doc, sheet, "F6");
|
XSSFCell standCell = getCellByRef(doc, sheet, "F6");
|
||||||
standCell.setCellValue(new Date());
|
standCell.setCellValue(new Date());
|
||||||
|
|
||||||
CellReference cr = new CellReference("A11");
|
CellReference cr = new CellReference("A11");
|
||||||
XSSFRow referenceRow = sheet.getRow(cr.getRow());
|
XSSFRow referenceRow = sheet.getRow(cr.getRow());
|
||||||
int referenceRowPos = referenceRow.getRowNum() + 1;
|
int referenceRowPos = referenceRow.getRowNum() + 1;
|
||||||
int rowPos = referenceRowPos;
|
int rowPos = referenceRowPos;
|
||||||
// int lastRow = sheet.getLastRowNum();
|
// int lastRow = sheet.getLastRowNum();
|
||||||
int lastRow = 999;
|
int lastRow = 999;
|
||||||
logger.finest("Last rownum=" + lastRow);
|
logger.finest("Last rownum=" + lastRow);
|
||||||
sheet.shiftRows(rowPos, lastRow, invoices.size(), true, true);
|
sheet.shiftRows(rowPos, lastRow, invoices.size(), true, true);
|
||||||
|
|
||||||
for (ItemCollection invoice : invoices) {
|
for (ItemCollection invoice : invoices) {
|
||||||
logger.finest("......copy row...");
|
logger.finest("......copy row...");
|
||||||
|
|
||||||
// now create a new line..
|
// now create a new line..
|
||||||
XSSFRow row = sheet.createRow(rowPos);
|
XSSFRow row = sheet.createRow(rowPos);
|
||||||
row.copyRowFrom(referenceRow, new CellCopyPolicy());
|
row.copyRowFrom(referenceRow, new CellCopyPolicy());
|
||||||
// insert values
|
// insert values
|
||||||
row.getCell(0).setCellValue(invoice.getItemValueString("invoice.number"));
|
row.getCell(0).setCellValue(invoice.getItemValueString("invoice.number"));
|
||||||
row.getCell(1).setCellValue(invoice.getItemValueString("dbtr.number"));
|
row.getCell(1).setCellValue(invoice.getItemValueString("dbtr.number"));
|
||||||
row.getCell(2).setCellValue(invoice.getItemValueString("space.name"));
|
row.getCell(2).setCellValue(invoice.getItemValueString("space.name"));
|
||||||
row.getCell(3).setCellValue(invoice.getItemValueString("invoice.text"));
|
row.getCell(3).setCellValue(invoice.getItemValueString("invoice.text"));
|
||||||
row.getCell(4).setCellValue(invoice.getItemValueDate("invoice.date"));
|
row.getCell(4).setCellValue(invoice.getItemValueDate("invoice.date"));
|
||||||
row.getCell(5).setCellValue(invoice.getItemValueDate("invoice.duedate"));
|
row.getCell(5).setCellValue(invoice.getItemValueDate("invoice.duedate"));
|
||||||
row.getCell(6).setCellValue(invoice.getItemValueDouble("invoice.total"));
|
row.getCell(6).setCellValue(invoice.getItemValueDouble("invoice.total"));
|
||||||
|
|
||||||
rowPos++;
|
rowPos++;
|
||||||
}
|
}
|
||||||
// delete reference row
|
// delete reference row
|
||||||
sheet.shiftRows(referenceRowPos, lastRow + invoices.size(), -1, true, true);
|
sheet.shiftRows(referenceRowPos, lastRow + invoices.size(), -1, true, true);
|
||||||
|
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
// write back the file
|
// write back the file
|
||||||
doc.write(byteArrayOutputStream);
|
doc.write(byteArrayOutputStream);
|
||||||
doc.close();
|
doc.close();
|
||||||
byte[] newContent = byteArrayOutputStream.toByteArray();
|
byte[] newContent = byteArrayOutputStream.toByteArray();
|
||||||
fileData.setContent(newContent);
|
fileData.setContent(newContent);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginException(ZahlungsavisExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
throw new PluginException(ZahlungsavisExportAdapter.class.getSimpleName(), ERROR_CONFIG,
|
||||||
"failed to update excel export: " + e.getMessage());
|
"failed to update excel export: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Cell by name or an optional absolute cell postion
|
* Returns a Cell by name or an optional absolute cell postion
|
||||||
* <p>
|
* <p>
|
||||||
* Examples for refs are 'A1', 'AB3', 'MyCell' where 'MyCell' is a named cell.
|
* Examples for refs are 'A1', 'AB3', 'MyCell' where 'MyCell' is a named cell.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static XSSFCell getCellByRef(XSSFWorkbook doc, XSSFSheet sheet, String cellReference) {
|
public static XSSFCell getCellByRef(XSSFWorkbook doc, XSSFSheet sheet, String cellReference) {
|
||||||
XSSFCell cell = null;
|
XSSFCell cell = null;
|
||||||
|
|
||||||
// first we test if the cellName is a named cell
|
// first we test if the cellName is a named cell
|
||||||
Name aNamedCell = doc.getName(cellReference);
|
Name aNamedCell = doc.getName(cellReference);
|
||||||
if (aNamedCell != null) {
|
if (aNamedCell != null) {
|
||||||
// yes its a named cell so we need to get the referrer Formula
|
// yes its a named cell so we need to get the referrer Formula
|
||||||
logger.finest("...resolving named cell = " + aNamedCell.getNameName());
|
logger.finest("...resolving named cell = " + aNamedCell.getNameName());
|
||||||
cellReference = aNamedCell.getRefersToFormula();
|
cellReference = aNamedCell.getRefersToFormula();
|
||||||
// now we can find the cell by its ref
|
// now we can find the cell by its ref
|
||||||
}
|
}
|
||||||
|
|
||||||
CellReference cr = new CellReference(cellReference);
|
CellReference cr = new CellReference(cellReference);
|
||||||
XSSFRow row = sheet.getRow(cr.getRow());
|
XSSFRow row = sheet.getRow(cr.getRow());
|
||||||
if (row == null) {
|
if (row == null) {
|
||||||
logger.severe("Unable to resolve cell ref '" + cellReference + "'!");
|
logger.severe("Unable to resolve cell ref '" + cellReference + "'!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
cell = row.getCell(cr.getCol());
|
cell = row.getCell(cr.getCol());
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der InkassoAppendAdapter verknüpft eine Rechnung mit einem Inkasso Workflow
|
* Der InkassoAppendAdapter verknüpft eine Rechnung mit einem Inkasso Workflow
|
||||||
* zum aktuellen Debitor. Existiert aktuell kein Inkasso für diesen
|
* zum aktuellen Debitor. Existiert aktuell kein Inkasso für diesen Debitor
|
||||||
* Debitor erzeugt der Adapter automatisch eine neue Prozessinstanz.
|
* erzeugt der Adapter automatisch eine neue Prozessinstanz.
|
||||||
* <p>
|
* <p>
|
||||||
* Wurde die Rechnung bereits einem Inkasso zugeordnet passiert nichts.
|
* Wurde die Rechnung bereits einem Inkasso zugeordnet passiert nichts.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -41,9 +41,9 @@ public class InkassoAppendAdapter implements SignalAdapter {
|
||||||
WorkflowService workflowService;
|
WorkflowService workflowService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Inkasso and adds a reference
|
* This method finds or create the Inkasso and adds a reference ($workitemref)
|
||||||
* ($workitemref) to the current invoice.
|
* to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -59,9 +59,9 @@ public class InkassoAppendAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese method hängt eine referenz der aktuellen Rechnung an den Inkasso
|
* Diese method hängt eine referenz der aktuellen Rechnung an den Inkasso
|
||||||
* Workflow an. Gibt es noch keinen, wird einer erzeugt.
|
* Workflow an. Gibt es noch keinen, wird einer erzeugt. Die method liefert das
|
||||||
* Die method liefert das Inkasso Workitem zurück.
|
* Inkasso Workitem zurück.
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -103,7 +103,7 @@ public class InkassoAppendAdapter implements SignalAdapter {
|
||||||
/**
|
/**
|
||||||
* Prüft alle offenen Inkasso Workflows und gibt den neuesten zur angegebenen
|
* Prüft alle offenen Inkasso Workflows und gibt den neuesten zur angegebenen
|
||||||
* dbtrNumber zurück, oder null falls es keinen Offenen gibt.
|
* dbtrNumber zurück, oder null falls es keinen Offenen gibt.
|
||||||
*
|
*
|
||||||
* @param dbtrNumber
|
* @param dbtrNumber
|
||||||
* @return
|
* @return
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@ import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der InkassoController dient dazu eine bereits zugewiesene Rechnung
|
* Der InkassoController dient dazu eine bereits zugewiesene Rechnung wieder aus
|
||||||
* wieder aus dem Inkasso zu entfernen.
|
* dem Inkasso zu entfernen.
|
||||||
* <p>
|
* <p>
|
||||||
* Zusätzlich bietet er die Summenberechnung an, bei der die Gutschriften
|
* Zusätzlich bietet er die Summenberechnung an, bei der die Gutschriften
|
||||||
* abgezogen werden.
|
* abgezogen werden.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -43,7 +43,7 @@ public class InkassoController implements Serializable {
|
||||||
* result is rounded to 2 digits.
|
* result is rounded to 2 digits.
|
||||||
* <p>
|
* <p>
|
||||||
* Gutschriften werden abgezogen
|
* Gutschriften werden abgezogen
|
||||||
*
|
*
|
||||||
* @param refids - list of workitem uniqueIds
|
* @param refids - list of workitem uniqueIds
|
||||||
* @param item - name of the item to summarize
|
* @param item - name of the item to summarize
|
||||||
* @return sum rounded to 2 digits
|
* @return sum rounded to 2 digits
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der ZahlungsavisAdapter importiert eine Excel Datei aus einem Textblock
|
* Der ZahlungsavisAdapter importiert eine Excel Datei aus einem Textblock
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
<inkasso name="textblock">textblock-ref</inkasso>
|
<inkasso name="textblock">textblock-ref</inkasso>
|
||||||
|
|
@ -38,7 +38,7 @@ import jakarta.inject.Inject;
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
|
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
|
||||||
* (siehe POIFineReplaceAdapter).
|
* (siehe POIFineReplaceAdapter).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
|
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
|
||||||
* 16 eingefügt werden.
|
* 16 eingefügt werden.
|
||||||
|
|
@ -46,7 +46,7 @@ import jakarta.inject.Inject;
|
||||||
* Dabei werden Gutschriften in spalte E und Rechnungen in Spalte F eingetrgen.
|
* Dabei werden Gutschriften in spalte E und Rechnungen in Spalte F eingetrgen.
|
||||||
* <p>
|
* <p>
|
||||||
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -69,7 +69,7 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Zahlungsavis and adds a reference
|
* This method finds or create the Zahlungsavis and adds a reference
|
||||||
* ($workitemref) to the current invoice.
|
* ($workitemref) to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -121,7 +121,7 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
|
||||||
* <p>
|
* <p>
|
||||||
* The named cell 'TOTAL' should contain the summary formula. It will be
|
* The named cell 'TOTAL' should contain the summary formula. It will be
|
||||||
* evaluated at the end.
|
* evaluated at the end.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -186,7 +186,7 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
|
||||||
/**
|
/**
|
||||||
* This method loads a text-block for a specified ref and appends the named
|
* This method loads a text-block for a specified ref and appends the named
|
||||||
* fileData object of this document.
|
* fileData object of this document.
|
||||||
*
|
*
|
||||||
* @param document
|
* @param document
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -216,9 +216,9 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a text-block ItemCollection for a specified name.
|
* This method returns a text-block ItemCollection for a specified name.
|
||||||
*
|
*
|
||||||
* @param name in attribute txtname
|
* @param name in attribute txtname
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public FileData loadTextBlockFileData(String name, String fileName) {
|
public FileData loadTextBlockFileData(String name, String fileName) {
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,10 @@ import jakarta.inject.Inject;
|
||||||
* processed invoices. This item is used in the Workflow Model to construct a
|
* processed invoices. This item is used in the Workflow Model to construct a
|
||||||
* HTML Table wen sending the mail.
|
* HTML Table wen sending the mail.
|
||||||
* <p>
|
* <p>
|
||||||
* The Adapter also splits the item 'dbtr.mail' into a multi value field if
|
* The Adapter also splits the item 'dbtr.mail' into a multi value field if the
|
||||||
* the value contains email addresses separated with new lines.
|
* value contains email addresses separated with new lines.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -52,7 +52,7 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method finds all invices ($workitemref) and tirgges event 300
|
* This method finds all invices ($workitemref) and tirgges event 300
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
@ -125,24 +125,24 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (invoice.getTaskID()) {
|
switch (invoice.getTaskID()) {
|
||||||
case 5200:
|
case 5200:
|
||||||
case 5201:
|
case 5201:
|
||||||
if (dunningLevel < 1)
|
if (dunningLevel < 1)
|
||||||
dunningLevel = 1;
|
dunningLevel = 1;
|
||||||
break;
|
break;
|
||||||
case 5210:
|
case 5210:
|
||||||
case 5211:
|
case 5211:
|
||||||
if (dunningLevel < 2)
|
if (dunningLevel < 2)
|
||||||
dunningLevel = 2;
|
dunningLevel = 2;
|
||||||
break;
|
break;
|
||||||
case 5220:
|
case 5220:
|
||||||
if (dunningLevel < 3)
|
if (dunningLevel < 3)
|
||||||
dunningLevel = 3;
|
dunningLevel = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (dunningLevel < 1)
|
if (dunningLevel < 1)
|
||||||
dunningLevel = 1;
|
dunningLevel = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a workitem stub for the mail message
|
// create a workitem stub for the mail message
|
||||||
|
|
@ -179,18 +179,18 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
|
||||||
// compute subject
|
// compute subject
|
||||||
switch (dunningLevel) {
|
switch (dunningLevel) {
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
mahnLaufWorkitem.setItemValue("mail.subject_de", "2. MAHNUNG");
|
mahnLaufWorkitem.setItemValue("mail.subject_de", "2. MAHNUNG");
|
||||||
mahnLaufWorkitem.setItemValue("mail.subject_en", "2. REMINDER");
|
mahnLaufWorkitem.setItemValue("mail.subject_en", "2. REMINDER");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
mahnLaufWorkitem.setItemValue("mail.subject_de", "LETZTE AUSSERGERICHTLICHE MAHNUNG");
|
mahnLaufWorkitem.setItemValue("mail.subject_de", "LETZTE AUSSERGERICHTLICHE MAHNUNG");
|
||||||
mahnLaufWorkitem.setItemValue("mail.subject_en", "LAST REMINDER");
|
mahnLaufWorkitem.setItemValue("mail.subject_en", "LAST REMINDER");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mahnLaufWorkitem.setItemValue("mail.subject_de", "1. MAHNUNG");
|
mahnLaufWorkitem.setItemValue("mail.subject_de", "1. MAHNUNG");
|
||||||
mahnLaufWorkitem.setItemValue("mail.subject_en", "1. REMINDER");
|
mahnLaufWorkitem.setItemValue("mail.subject_en", "1. REMINDER");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the dbtr.mail item (split into multi value)
|
// Verify the dbtr.mail item (split into multi value)
|
||||||
|
|
@ -198,8 +198,7 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
|
||||||
for (String mail : mailListe) {
|
for (String mail : mailListe) {
|
||||||
logger.fine(" test mail address:'" + mail + "'");
|
logger.fine(" test mail address:'" + mail + "'");
|
||||||
if (!InvoiceUtil.validateEmail(mail)) {
|
if (!InvoiceUtil.validateEmail(mail)) {
|
||||||
throw new PluginException(MahnlaufExecuteAdapter.class.getName(),
|
throw new PluginException(MahnlaufExecuteAdapter.class.getName(), "INVALID_EMAIL",
|
||||||
"INVALID_EMAIL",
|
|
||||||
"Die Daten konnten nicht aktualisiert werden! Bitte geben Sie eine gültige E-Mail Adresse ein!");
|
"Die Daten konnten nicht aktualisiert werden! Bitte geben Sie eine gültige E-Mail Adresse ein!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +207,7 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the reminder date is today or in the past
|
* Returns true if the reminder date is today or in the past
|
||||||
*
|
*
|
||||||
* @param uniqueid
|
* @param uniqueid
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -30,152 +30,151 @@ import jakarta.inject.Inject;
|
||||||
* <p>
|
* <p>
|
||||||
* If the invoice has already been linked to a Mahnlauf nothing happens.
|
* If the invoice has already been linked to a Mahnlauf nothing happens.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
public class MahnlaufRefAddAdapter implements SignalAdapter {
|
public class MahnlaufRefAddAdapter implements SignalAdapter {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(MahnlaufRefAddAdapter.class.getName());
|
private static Logger logger = Logger.getLogger(MahnlaufRefAddAdapter.class.getName());
|
||||||
|
|
||||||
@EJB
|
@EJB
|
||||||
ModelService modelService;
|
ModelService modelService;
|
||||||
|
|
||||||
@EJB
|
@EJB
|
||||||
WorkflowService workflowService = null;
|
WorkflowService workflowService = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SepaWorkflowService sepaWorkflowService;
|
SepaWorkflowService sepaWorkflowService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BusinessPartnerService businessPartnerService;
|
BusinessPartnerService businessPartnerService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method finds or create the Mahnlauf and adds a reference ($workitemref)
|
* This method finds or create the Mahnlauf and adds a reference ($workitemref)
|
||||||
* to the current invoice.
|
* to the current invoice.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection execute(ItemCollection invoice, ItemCollection event)
|
public ItemCollection execute(ItemCollection invoice, ItemCollection event)
|
||||||
throws AdapterException, PluginException {
|
throws AdapterException, PluginException {
|
||||||
|
|
||||||
if (invoice.getTaskID() < MahnlaufService.TASK_MAHNLAUF_START
|
if (invoice.getTaskID() < MahnlaufService.TASK_MAHNLAUF_START
|
||||||
|| invoice.getTaskID() > MahnlaufService.TASK_MAHNLAUF_END) {
|
|| invoice.getTaskID() > MahnlaufService.TASK_MAHNLAUF_END) {
|
||||||
throw new PluginException(MahnlaufRefAddAdapter.class.getName(),
|
throw new PluginException(MahnlaufRefAddAdapter.class.getName(), MahnlaufService.ERROR_CONFIG,
|
||||||
MahnlaufService.ERROR_CONFIG,
|
"Der Mahnlauf kann nur für Rechnungen erstellt werden die bereits die Fälligkeit erreicht haben.");
|
||||||
"Der Mahnlauf kann nur für Rechnungen erstellt werden die bereits die Fälligkeit erreicht haben.");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
String dbtrNumber = invoice.getItemValueString(MahnlaufService.ITEM_DBTR_NUMBER);
|
String dbtrNumber = invoice.getItemValueString(MahnlaufService.ITEM_DBTR_NUMBER);
|
||||||
ItemCollection mahnLaufWorkitem;
|
ItemCollection mahnLaufWorkitem;
|
||||||
try {
|
try {
|
||||||
mahnLaufWorkitem = findMahnlauf(dbtrNumber);
|
mahnLaufWorkitem = findMahnlauf(dbtrNumber);
|
||||||
|
|
||||||
if (mahnLaufWorkitem == null) {
|
if (mahnLaufWorkitem == null) {
|
||||||
// create one...
|
// create one...
|
||||||
mahnLaufWorkitem = createNewMahnlauf(dbtrNumber, invoice, event);
|
mahnLaufWorkitem = createNewMahnlauf(dbtrNumber, invoice, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add Invoice to Mahnlauf
|
// add Invoice to Mahnlauf
|
||||||
List<String> refList = mahnLaufWorkitem.getItemValue("$workitemref");
|
List<String> refList = mahnLaufWorkitem.getItemValue("$workitemref");
|
||||||
if (!refList.contains(invoice.getUniqueID())) {
|
if (!refList.contains(invoice.getUniqueID())) {
|
||||||
mahnLaufWorkitem.appendItemValueUnique("$workitemref", invoice.getUniqueID());
|
mahnLaufWorkitem.appendItemValueUnique("$workitemref", invoice.getUniqueID());
|
||||||
}
|
}
|
||||||
|
|
||||||
// set event 100 and process
|
// set event 100 and process
|
||||||
ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
|
ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
|
||||||
int eventID = mahnlaufConfig.getItemValueInteger("event");
|
int eventID = mahnlaufConfig.getItemValueInteger("event");
|
||||||
|
|
||||||
mahnLaufWorkitem.event(eventID);
|
mahnLaufWorkitem.event(eventID);
|
||||||
workflowService.processWorkItem(mahnLaufWorkitem);
|
workflowService.processWorkItem(mahnLaufWorkitem);
|
||||||
|
|
||||||
} catch (QueryException | ModelException e) {
|
} catch (QueryException | ModelException e) {
|
||||||
throw new PluginException(MahnlaufRefAddAdapter.class.getName(),
|
throw new PluginException(MahnlaufRefAddAdapter.class.getName(), MahnlaufService.ERROR_CONFIG,
|
||||||
MahnlaufService.ERROR_CONFIG, "Unable to create Mahnlauf", e);
|
"Unable to create Mahnlauf", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set mahnlauf ref
|
// set mahnlauf ref
|
||||||
invoice.setItemValue("dunning.ref", mahnLaufWorkitem.getUniqueID());
|
invoice.setItemValue("dunning.ref", mahnLaufWorkitem.getUniqueID());
|
||||||
return invoice;
|
return invoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method finds an open mahnlauf for a debtr.numbre (name)
|
* Helper method finds an open mahnlauf for a debtr.numbre (name)
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
* @throws QueryException
|
* @throws QueryException
|
||||||
*/
|
*/
|
||||||
public ItemCollection findMahnlauf(String key) throws QueryException {
|
public ItemCollection findMahnlauf(String key) throws QueryException {
|
||||||
String query = "(type:workitem) AND ($modelversion:mahnlauf*) AND (name:\"" + key + "\")";
|
String query = "(type:workitem) AND ($modelversion:mahnlauf*) AND (name:\"" + key + "\")";
|
||||||
List<ItemCollection> resultList = workflowService.getDocumentService().find(query, 1, 0, "$modified", true);
|
List<ItemCollection> resultList = workflowService.getDocumentService().find(query, 1, 0, "$modified", true);
|
||||||
|
|
||||||
if (resultList.size() > 0) {
|
if (resultList.size() > 0) {
|
||||||
return resultList.get(0);
|
return resultList.get(0);
|
||||||
}
|
}
|
||||||
// no mahnaluffound
|
// no mahnaluffound
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to create a new Mahnlauf workitem
|
* Helper method to create a new Mahnlauf workitem
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @param invoice
|
* @param invoice
|
||||||
* @return
|
* @return
|
||||||
* @throws ModelException
|
* @throws ModelException
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public ItemCollection createNewMahnlauf(String key, ItemCollection invoice, ItemCollection event)
|
public ItemCollection createNewMahnlauf(String key, ItemCollection invoice, ItemCollection event)
|
||||||
throws ModelException, PluginException {
|
throws ModelException, PluginException {
|
||||||
String modelVersion = null;
|
String modelVersion = null;
|
||||||
int taskID = -1;
|
int taskID = -1;
|
||||||
int eventID = -1;
|
int eventID = -1;
|
||||||
// test if the event provides a sepa export configuration
|
// test if the event provides a sepa export configuration
|
||||||
ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
|
ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
|
||||||
if (mahnlaufConfig != null && mahnlaufConfig.hasItem("modelversion") && mahnlaufConfig.hasItem("task")) {
|
if (mahnlaufConfig != null && mahnlaufConfig.hasItem("modelversion") && mahnlaufConfig.hasItem("task")) {
|
||||||
logger.fine("read model information from event");
|
logger.fine("read model information from event");
|
||||||
modelVersion = mahnlaufConfig.getItemValueString("modelVersion");
|
modelVersion = mahnlaufConfig.getItemValueString("modelVersion");
|
||||||
taskID = mahnlaufConfig.getItemValueInteger("task");
|
taskID = mahnlaufConfig.getItemValueInteger("task");
|
||||||
eventID = mahnlaufConfig.getItemValueInteger("event");
|
eventID = mahnlaufConfig.getItemValueInteger("event");
|
||||||
}
|
}
|
||||||
|
|
||||||
// build the sepa export workitem....
|
// build the sepa export workitem....
|
||||||
ItemCollection mahnlaufWorkitem = new ItemCollection().model(modelVersion).task(taskID);
|
ItemCollection mahnlaufWorkitem = new ItemCollection().model(modelVersion).task(taskID);
|
||||||
mahnlaufWorkitem.replaceItemValue("name", key);
|
mahnlaufWorkitem.replaceItemValue("name", key);
|
||||||
mahnlaufWorkitem.replaceItemValue(WorkflowKernel.CREATED, new Date());
|
mahnlaufWorkitem.replaceItemValue(WorkflowKernel.CREATED, new Date());
|
||||||
mahnlaufWorkitem.replaceItemValue(WorkflowKernel.MODIFIED, new Date());
|
mahnlaufWorkitem.replaceItemValue(WorkflowKernel.MODIFIED, new Date());
|
||||||
// set unqiueid
|
// set unqiueid
|
||||||
mahnlaufWorkitem.setItemValue(WorkflowKernel.UNIQUEID, WorkflowKernel.generateUniqueID());
|
mahnlaufWorkitem.setItemValue(WorkflowKernel.UNIQUEID, WorkflowKernel.generateUniqueID());
|
||||||
|
|
||||||
// copy dbtr_iban
|
// copy dbtr_iban
|
||||||
mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NAME,
|
mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NAME,
|
||||||
invoice.getItemValue(MahnlaufService.ITEM_DBTR_NAME));
|
invoice.getItemValue(MahnlaufService.ITEM_DBTR_NAME));
|
||||||
|
|
||||||
// lookup email....
|
// lookup email....
|
||||||
String dbtrNumber = invoice.getItemValueString("dbtr.number");
|
String dbtrNumber = invoice.getItemValueString("dbtr.number");
|
||||||
ItemCollection businessPartner = businessPartnerService
|
ItemCollection businessPartner = businessPartnerService
|
||||||
.getBusinessPartnerByID(InvoiceUtil.buildBPID(dbtrNumber));
|
.getBusinessPartnerByID(InvoiceUtil.buildBPID(dbtrNumber));
|
||||||
if (businessPartner != null) {
|
if (businessPartner != null) {
|
||||||
mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_EMAIL, businessPartner.getItemValue("dbtr.mail"));// dbtr.mail
|
mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_EMAIL, businessPartner.getItemValue("dbtr.mail"));// dbtr.mail
|
||||||
}
|
}
|
||||||
|
|
||||||
mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NUMBER,
|
mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NUMBER,
|
||||||
invoice.getItemValue(MahnlaufService.ITEM_DBTR_NUMBER));
|
invoice.getItemValue(MahnlaufService.ITEM_DBTR_NUMBER));
|
||||||
mahnlaufWorkitem.setItemValue("invoice.language", invoice.getItemValue("invoice.language"));
|
mahnlaufWorkitem.setItemValue("invoice.language", invoice.getItemValue("invoice.language"));
|
||||||
|
|
||||||
// set workflow group name from the Task Element to identify document in xslt
|
// set workflow group name from the Task Element to identify document in xslt
|
||||||
Model model = modelService.getModel(modelVersion);
|
Model model = modelService.getModel(modelVersion);
|
||||||
ItemCollection task = model.getTask(taskID);
|
ItemCollection task = model.getTask(taskID);
|
||||||
String modelTaskGroupName = task.getItemValueString("txtworkflowgroup"); // DO NOT CHANGE!
|
String modelTaskGroupName = task.getItemValueString("txtworkflowgroup"); // DO NOT CHANGE!
|
||||||
mahnlaufWorkitem.setItemValue(WorkflowKernel.WORKFLOWGROUP, modelTaskGroupName);
|
mahnlaufWorkitem.setItemValue(WorkflowKernel.WORKFLOWGROUP, modelTaskGroupName);
|
||||||
|
|
||||||
logger.info("...created new mahnlauf " + key + "...");
|
logger.info("...created new mahnlauf " + key + "...");
|
||||||
|
|
||||||
return mahnlaufWorkitem;
|
return mahnlaufWorkitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow
|
* Imixs Workflow
|
||||||
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* http://www.imixs.org
|
* http://www.imixs.org
|
||||||
* http://java.net/projects/imixs-workflow
|
* http://java.net/projects/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
@ -49,11 +49,11 @@ import jakarta.ejb.Singleton;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der MahnlaufService wird vom MahnlaufExecuteAdapter um
|
* Der MahnlaufService wird vom MahnlaufExecuteAdapter um Ausgangsrechnungen zu
|
||||||
* Ausgangsrechnungen zu akutalisieren.
|
* akutalisieren.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||||
|
|
@ -87,7 +87,7 @@ public class MahnlaufService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * Diese Method processed eine Invoice mit Manager Rechnten
|
* * Diese Method processed eine Invoice mit Manager Rechnten
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws ModelException
|
* @throws ModelException
|
||||||
* @throws ProcessingErrorException
|
* @throws ProcessingErrorException
|
||||||
|
|
@ -104,7 +104,7 @@ public class MahnlaufService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method that loads all expressions from the spaces
|
* Helper method that loads all expressions from the spaces
|
||||||
*
|
*
|
||||||
* @return List of list of expressions
|
* @return List of list of expressions
|
||||||
*/
|
*/
|
||||||
public Map<String, List<String>> loadSpacePosMappings() {
|
public Map<String, List<String>> loadSpacePosMappings() {
|
||||||
|
|
@ -125,7 +125,7 @@ public class MahnlaufService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode zum errechnen des richtigen Spaces zu einer invoice.text Positon
|
* Hilfsmethode zum errechnen des richtigen Spaces zu einer invoice.text Positon
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @param spacePosMappings
|
* @param spacePosMappings
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
/*
|
/*
|
||||||
* Imixs-Workflow
|
* Imixs-Workflow
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* https://www.imixs.org
|
* https://www.imixs.org
|
||||||
* https://github.com/imixs/imixs-workflow
|
* https://github.com/imixs/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - Project Management
|
* Imixs Software Solutions GmbH - Project Management
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*/
|
*/
|
||||||
|
|
@ -59,11 +59,10 @@ import jakarta.enterprise.event.Observes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der BusinessPartnerImportService hängt sich an den standard CSVImport Service
|
* Der BusinessPartnerImportService hängt sich an den standard CSVImport Service
|
||||||
* der die Cargosoft Stammdaten aktualisiert.
|
* der die Cargosoft Stammdaten aktualisiert. Es ist ein simples Observer
|
||||||
* Es ist ein simples Observer Pattern das auf das Document Event
|
* Pattern das auf das Document Event "ON_DOCUMENT_SAVE" reagiert. Hier hängt
|
||||||
* "ON_DOCUMENT_SAVE" reagiert. Hier hängt sich der BusinessPartnerImportService
|
* sich der BusinessPartnerImportService ein und prüft ob der Workflow schon
|
||||||
* ein und prüft ob der Workflow schon existiert oder ggf. aktualisiert werden
|
* existiert oder ggf. aktualisiert werden muss.
|
||||||
* muss.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Der Service migriert auch die alten zusätzlichen IBAN/BIC felder wenn der
|
* Der Service migriert auch die alten zusätzlichen IBAN/BIC felder wenn der
|
||||||
* Business partner erstmals neu angelegt wird.
|
* Business partner erstmals neu angelegt wird.
|
||||||
|
|
@ -73,7 +72,7 @@ import jakarta.enterprise.event.Observes;
|
||||||
* <p>
|
* <p>
|
||||||
* Im Cargosoft Entity wird zusätzlich das flag NOSNAPSHOT=true gesetzt. Dies
|
* Im Cargosoft Entity wird zusätzlich das flag NOSNAPSHOT=true gesetzt. Dies
|
||||||
* ist nur eine Performance Optimierung.
|
* ist nur eine Performance Optimierung.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -107,8 +106,8 @@ public class BusinessPartnerImportService {
|
||||||
/**
|
/**
|
||||||
* Die Methode reagiert auf das CDI DocumentEvent beim Import von cargosoft
|
* Die Methode reagiert auf das CDI DocumentEvent beim Import von cargosoft
|
||||||
* cargosoftkreditor documenten.
|
* cargosoftkreditor documenten.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void onEvent(@Observes DocumentEvent event) {
|
public void onEvent(@Observes DocumentEvent event) {
|
||||||
|
|
||||||
|
|
@ -138,9 +137,9 @@ public class BusinessPartnerImportService {
|
||||||
/**
|
/**
|
||||||
* Syncnrhonisert ein drecks Cargosoft Objekt mit dem neuen Busienss partner
|
* Syncnrhonisert ein drecks Cargosoft Objekt mit dem neuen Busienss partner
|
||||||
* objekt
|
* objekt
|
||||||
*
|
*
|
||||||
* Gibt true urück wenn sich was verädnert hat
|
* Gibt true urück wenn sich was verädnert hat
|
||||||
*
|
*
|
||||||
* @param creditor
|
* @param creditor
|
||||||
*/
|
*/
|
||||||
public boolean syncCargosoftCreditorBusinessPartner(ItemCollection importDoc) {
|
public boolean syncCargosoftCreditorBusinessPartner(ItemCollection importDoc) {
|
||||||
|
|
@ -218,7 +217,7 @@ public class BusinessPartnerImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt ein neues leeres Business Partner Object
|
* Erstellt ein neues leeres Business Partner Object
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private ItemCollection createBusinessPartner(String partnerID) {
|
private ItemCollection createBusinessPartner(String partnerID) {
|
||||||
|
|
@ -340,7 +339,7 @@ public class BusinessPartnerImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sucht nach einem Business partner
|
* Sucht nach einem Business partner
|
||||||
*
|
*
|
||||||
* @param id
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
/*
|
/*
|
||||||
* Imixs-Workflow
|
* Imixs-Workflow
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* https://www.imixs.org
|
* https://www.imixs.org
|
||||||
* https://github.com/imixs/imixs-workflow
|
* https://github.com/imixs/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - Project Management
|
* Imixs Software Solutions GmbH - Project Management
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*/
|
*/
|
||||||
|
|
@ -89,20 +89,19 @@ import jakarta.enterprise.event.Observes;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der CargosoftXMLEAkteImportService erweitert den FTPImportService und
|
* Der CargosoftXMLEAkteImportService erweitert den FTPImportService und kann
|
||||||
* kann XML EAkten (Steuerbescheide) von Cargosoft importieren.
|
* XML EAkten (Steuerbescheide) von Cargosoft importieren. Der Service reagiert
|
||||||
* Der Service reagiert auf DocumentImportEvents und kann über das Options Feld
|
* auf DocumentImportEvents und kann über das Options Feld konfiguriert werden.
|
||||||
* konfiguriert werden.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
|
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
|
||||||
* speziellen Verfahren geparsed und dann als Steuerbescheid importiert.
|
* speziellen Verfahren geparsed und dann als Steuerbescheid importiert.
|
||||||
* <p>
|
* <p>
|
||||||
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt
|
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt diese
|
||||||
* diese beim Import nicht mit der Mandanten Nummer in der XML Datei überein,
|
* beim Import nicht mit der Mandanten Nummer in der XML Datei überein, wird das
|
||||||
* wird das XML Dokument gelöscht und nicht importiert.
|
* XML Dokument gelöscht und nicht importiert.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -135,8 +134,8 @@ public class CargosoftXMLEAkteImportService {
|
||||||
/**
|
/**
|
||||||
* This method reacts on a CDI ImportEvent and reads documents form a ftp
|
* This method reacts on a CDI ImportEvent and reads documents form a ftp
|
||||||
* server.
|
* server.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void onEvent(@Observes DocumentImportEvent event) {
|
public void onEvent(@Observes DocumentImportEvent event) {
|
||||||
|
|
||||||
|
|
@ -162,8 +161,7 @@ public class CargosoftXMLEAkteImportService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
documentImportService.logMessage("...CARGOSOFT_EAKTE_XML Import started: mandant.id=" + mandantID,
|
documentImportService.logMessage("...CARGOSOFT_EAKTE_XML Import started: mandant.id=" + mandantID, event);
|
||||||
event);
|
|
||||||
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
|
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
|
||||||
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
|
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
|
||||||
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
|
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
|
||||||
|
|
@ -216,8 +214,8 @@ public class CargosoftXMLEAkteImportService {
|
||||||
ftpClient.connect(ftpServer, ftpPort);
|
ftpClient.connect(ftpServer, ftpPort);
|
||||||
|
|
||||||
if (ftpClient.login(ftpUser, ftpPassword) == false) {
|
if (ftpClient.login(ftpUser, ftpPassword) == false) {
|
||||||
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
|
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
|
||||||
"FTP_ERROR", "FTP file transfer failed: login failed!");
|
"FTP file transfer failed: login failed!");
|
||||||
}
|
}
|
||||||
ftpClient.enterLocalPassiveMode();
|
ftpClient.enterLocalPassiveMode();
|
||||||
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
|
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
|
||||||
|
|
@ -225,8 +223,7 @@ public class CargosoftXMLEAkteImportService {
|
||||||
ftpClient.setControlEncoding("UTF-8");
|
ftpClient.setControlEncoding("UTF-8");
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
|
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
|
||||||
"FTP_ERROR", e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ftpClient;
|
return ftpClient;
|
||||||
|
|
@ -234,7 +231,7 @@ public class CargosoftXMLEAkteImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method reads the working FTP directory and starts importing the files.
|
* Helper method reads the working FTP directory and starts importing the files.
|
||||||
*
|
*
|
||||||
* @param ftpClient
|
* @param ftpClient
|
||||||
* @param ftpPath
|
* @param ftpPath
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
|
|
@ -250,8 +247,8 @@ public class CargosoftXMLEAkteImportService {
|
||||||
// try to enter the working directory and read all files...
|
// try to enter the working directory and read all files...
|
||||||
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
|
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
|
||||||
if (bWorkingDir == false) {
|
if (bWorkingDir == false) {
|
||||||
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
|
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
|
||||||
"FTP_ERROR", "...failed to change into working directory: ");
|
"...failed to change into working directory: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
|
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
|
||||||
|
|
@ -299,10 +296,10 @@ public class CargosoftXMLEAkteImportService {
|
||||||
// "processed/");
|
// "processed/");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
} catch (AccessDeniedException | ProcessingErrorException | PluginException
|
} catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException
|
||||||
| ModelException | XPathExpressionException | TransformerException e) {
|
| XPathExpressionException | TransformerException e) {
|
||||||
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
|
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
|
||||||
"FTP_ERROR", e.getMessage());
|
e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
documentImportService.logMessage("..." + count + " new files imported.", event);
|
documentImportService.logMessage("..." + count + " new files imported.", event);
|
||||||
|
|
@ -313,8 +310,7 @@ public class CargosoftXMLEAkteImportService {
|
||||||
int r = ftpClient.getReplyCode();
|
int r = ftpClient.getReplyCode();
|
||||||
logger.severe("FTP ReplyCode=" + r);
|
logger.severe("FTP ReplyCode=" + r);
|
||||||
|
|
||||||
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
|
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
|
||||||
"FTP_ERROR", e.getMessage());
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
// do logout....
|
// do logout....
|
||||||
|
|
@ -324,8 +320,7 @@ public class CargosoftXMLEAkteImportService {
|
||||||
ftpClient.disconnect();
|
ftpClient.disconnect();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
|
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
|
||||||
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
|
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
|
||||||
"FTP_ERROR", e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -333,8 +328,8 @@ public class CargosoftXMLEAkteImportService {
|
||||||
/**
|
/**
|
||||||
* Creates and processes a new workitem with a given xml information from the
|
* Creates and processes a new workitem with a given xml information from the
|
||||||
* filedata
|
* filedata
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws ModelException
|
* @throws ModelException
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
|
|
@ -344,9 +339,8 @@ public class CargosoftXMLEAkteImportService {
|
||||||
* @throws XPathExpressionException
|
* @throws XPathExpressionException
|
||||||
*/
|
*/
|
||||||
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
|
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
|
||||||
Map<String, List<String>> spacePosMappings)
|
Map<String, List<String>> spacePosMappings) throws AccessDeniedException, ProcessingErrorException,
|
||||||
throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException,
|
PluginException, ModelException, XPathExpressionException, TransformerException {
|
||||||
XPathExpressionException, TransformerException {
|
|
||||||
ItemCollection workitem = new ItemCollection();
|
ItemCollection workitem = new ItemCollection();
|
||||||
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
|
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
|
||||||
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
|
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
|
||||||
|
|
@ -375,37 +369,37 @@ public class CargosoftXMLEAkteImportService {
|
||||||
// invoice.rate
|
// invoice.rate
|
||||||
// invoice.base.amount
|
// invoice.base.amount
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='client']", workitem,
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='client']", workitem, "mandant.id",
|
||||||
"mandant.id", String.class);
|
String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_voucher_number']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_voucher_number']", workitem,
|
||||||
workitem, "invoice.number", String.class);
|
"invoice.number", String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_address_number']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_address_number']", workitem,
|
||||||
workitem, "cdtr.number", String.class);
|
"cdtr.number", String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='voucherdate']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='voucherdate']", workitem,
|
||||||
workitem, "invoice.date", Date.class);
|
"invoice.date", Date.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency']", workitem,
|
||||||
workitem, "invoice.currency", String.class);
|
"invoice.currency", String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency_rate']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency_rate']", workitem,
|
||||||
workitem, "invoice.rate", Double.class);
|
"invoice.rate", Double.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_net_amount']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_net_amount']", workitem,
|
||||||
workitem, "invoice.total.net", Double.class);
|
"invoice.total.net", Double.class);
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_tax_amount']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_tax_amount']", workitem,
|
||||||
workitem, "invoice.total.tax", Double.class);
|
"invoice.total.tax", Double.class);
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='reference']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='reference']", workitem,
|
||||||
workitem, "invoice.atc.number", String.class);
|
"invoice.atc.number", String.class);
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_period']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_period']", workitem,
|
||||||
workitem, "invoice.booking_period", String.class);
|
"invoice.booking_period", String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_date']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_date']", workitem,
|
||||||
workitem, "invoice.booking_date", Date.class);
|
"invoice.booking_date", Date.class);
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_text']",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_text']", workitem,
|
||||||
workitem, "invoice.booking_text", String.class);
|
"invoice.booking_text", String.class);
|
||||||
|
|
||||||
// verify if invoice is already imported.
|
// verify if invoice is already imported.
|
||||||
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
|
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
|
||||||
|
|
@ -440,8 +434,7 @@ public class CargosoftXMLEAkteImportService {
|
||||||
attacheFiles(doc, workitem);
|
attacheFiles(doc, workitem);
|
||||||
}
|
}
|
||||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||||
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
|
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "XML_ERROR", e.getMessage());
|
||||||
"XML_ERROR", e.getMessage());
|
|
||||||
}
|
}
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
@ -449,12 +442,11 @@ public class CargosoftXMLEAkteImportService {
|
||||||
/**
|
/**
|
||||||
* Reads a tag value from the xml tree and set the value into the given
|
* Reads a tag value from the xml tree and set the value into the given
|
||||||
* workitem.
|
* workitem.
|
||||||
*
|
*
|
||||||
* /Invoices/Invoice/InvoiceHeader/Client/Code
|
* /Invoices/Invoice/InvoiceHeader/Client/Code
|
||||||
*
|
*
|
||||||
* Beispiel Datum:
|
* Beispiel Datum: <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
|
||||||
* <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
|
*
|
||||||
*
|
|
||||||
* @param doc - xml doc
|
* @param doc - xml doc
|
||||||
* @param expression - xpath expression
|
* @param expression - xpath expression
|
||||||
* @param workitem
|
* @param workitem
|
||||||
|
|
@ -513,10 +505,10 @@ public class CargosoftXMLEAkteImportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method attache the pdf file and the XML file to the workitem.
|
* This method attache the pdf file and the XML file to the workitem. The method
|
||||||
* The method removes the file content first form the xml tree and attache the
|
* removes the file content first form the xml tree and attache the XML without
|
||||||
* XML without the pdf data.
|
* the pdf data.
|
||||||
*
|
*
|
||||||
* @throws XPathExpressionException
|
* @throws XPathExpressionException
|
||||||
* @throws TransformerException
|
* @throws TransformerException
|
||||||
*/
|
*/
|
||||||
|
|
@ -526,24 +518,23 @@ public class CargosoftXMLEAkteImportService {
|
||||||
XPathFactory xpathFactory = XPathFactory.newInstance();
|
XPathFactory xpathFactory = XPathFactory.newInstance();
|
||||||
XPath xpath = xpathFactory.newXPath();
|
XPath xpath = xpathFactory.newXPath();
|
||||||
// read filename and content....
|
// read filename and content....
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Filename",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Filename", workitem, "import.filename",
|
||||||
workitem, "import.filename", String.class);
|
String.class);
|
||||||
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Content",
|
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Content", workitem, "import.filedata",
|
||||||
workitem, "import.filedata", String.class);
|
String.class);
|
||||||
|
|
||||||
// attache the PDF file content
|
// attache the PDF file content
|
||||||
String fileDataString = workitem.getItemValueString("import.filedata");
|
String fileDataString = workitem.getItemValueString("import.filedata");
|
||||||
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
|
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
|
||||||
FileData fileData = new FileData(workitem.getItemValueString("import.filename"),
|
FileData fileData = new FileData(workitem.getItemValueString("import.filename"), decodedPDFData,
|
||||||
decodedPDFData, "application/pdf", null);
|
"application/pdf", null);
|
||||||
workitem.addFileData(fileData);
|
workitem.addFileData(fileData);
|
||||||
// remove the temp items..
|
// remove the temp items..
|
||||||
workitem.removeItem("import.filename");
|
workitem.removeItem("import.filename");
|
||||||
workitem.removeItem("import.filedata");
|
workitem.removeItem("import.filedata");
|
||||||
|
|
||||||
// next remove the Attachments/AttachmentContent from the dom tree
|
// next remove the Attachments/AttachmentContent from the dom tree
|
||||||
XPathExpression attachmentsExpr = xpath
|
XPathExpression attachmentsExpr = xpath.compile("/CargoSoftEFile/EFile/Attachments/Attachment/Content");
|
||||||
.compile("/CargoSoftEFile/EFile/Attachments/Attachment/Content");
|
|
||||||
NodeList contentNodes = (NodeList) attachmentsExpr.evaluate(doc, XPathConstants.NODESET);
|
NodeList contentNodes = (NodeList) attachmentsExpr.evaluate(doc, XPathConstants.NODESET);
|
||||||
// Remove the matching nodes
|
// Remove the matching nodes
|
||||||
for (int i = 0; i < contentNodes.getLength(); i++) {
|
for (int i = 0; i < contentNodes.getLength(); i++) {
|
||||||
|
|
@ -569,7 +560,7 @@ public class CargosoftXMLEAkteImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft ob die Belegnummer schon existiert (importiert wurde)
|
* Prüft ob die Belegnummer schon existiert (importiert wurde)
|
||||||
*
|
*
|
||||||
* @param belegNummer
|
* @param belegNummer
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -592,24 +583,23 @@ public class CargosoftXMLEAkteImportService {
|
||||||
/**
|
/**
|
||||||
* This helper method reads the references starting with 'Row_' and creates a
|
* This helper method reads the references starting with 'Row_' and creates a
|
||||||
* child Workitem for each row.
|
* child Workitem for each row.
|
||||||
*
|
*
|
||||||
* The method assumes that the rows are starting with the type 'row_n_' where
|
* The method assumes that the rows are starting with the type 'row_n_' where
|
||||||
* 'n' is the row number.
|
* 'n' is the row number. We start with row 1 and read until we found more rows.
|
||||||
* We start with row 1 and read until we found more rows.
|
*
|
||||||
*
|
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* ...
|
* ...
|
||||||
<Reference type="row_1_activity_type" />
|
<Reference type="row_1_activity_type" />
|
||||||
<Reference type="row_1_amount">3591.340</Reference>
|
<Reference type="row_1_amount">3591.340</Reference>
|
||||||
<Reference type="row_1_tax_code">0</Reference>
|
<Reference type="row_1_tax_code">0</Reference>
|
||||||
<Reference type="row_1_cs_filenumber">IM-GCA-2408-116</Reference>
|
<Reference type="row_1_cs_filenumber">IM-GCA-2408-116</Reference>
|
||||||
* }</pre>
|
* }</pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* The last filenumber text will be transferred into the item 'invoice.text'
|
* The last filenumber text will be transferred into the item 'invoice.text'
|
||||||
*
|
*
|
||||||
* @param xml
|
* @param xml
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
/*
|
/*
|
||||||
* Imixs-Workflow
|
* Imixs-Workflow
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* https://www.imixs.org
|
* https://www.imixs.org
|
||||||
* https://github.com/imixs/imixs-workflow
|
* https://github.com/imixs/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - Project Management
|
* Imixs Software Solutions GmbH - Project Management
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*/
|
*/
|
||||||
|
|
@ -89,22 +89,21 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der CargosoftXMLInvoiceImportImportService erweitert den FTPImportService und
|
* Der CargosoftXMLInvoiceImportImportService erweitert den FTPImportService und
|
||||||
* kann XML Invoice Dokumente von Cargosoft importieren.
|
* kann XML Invoice Dokumente von Cargosoft importieren. Der Service reagiert
|
||||||
* Der Service reagiert auf DocumentImportEvents und kann über das Options Feld
|
* auf DocumentImportEvents und kann über das Options Feld konfiguriert werden.
|
||||||
* konfiguriert werden.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
|
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
|
||||||
* speziellen Verfahren geparsed und dann als Ausgangsrechnungen importiert.
|
* speziellen Verfahren geparsed und dann als Ausgangsrechnungen importiert. Der
|
||||||
* Der Service ersetzt den alten DATEV Import. Falls eine Rechnung schon
|
* Service ersetzt den alten DATEV Import. Falls eine Rechnung schon existiert
|
||||||
* existiert (Rechnungsnummer) wird der Datensatz vom FTP Laufwerk gelöscht und
|
* (Rechnungsnummer) wird der Datensatz vom FTP Laufwerk gelöscht und nicht
|
||||||
* nicht importiert.
|
* importiert.
|
||||||
* <p>
|
* <p>
|
||||||
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt
|
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt diese
|
||||||
* diese beim Import nicht mit der Mandanten Nummer in der XML Datei überein,
|
* beim Import nicht mit der Mandanten Nummer in der XML Datei überein, wird das
|
||||||
* wird das XML Dokument gelöscht und nicht importiert.
|
* XML Dokument gelöscht und nicht importiert.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -137,8 +136,8 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
/**
|
/**
|
||||||
* This method reacts on a CDI ImportEvent and reads documents form a ftp
|
* This method reacts on a CDI ImportEvent and reads documents form a ftp
|
||||||
* server.
|
* server.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void onEvent(@Observes DocumentImportEvent event) {
|
public void onEvent(@Observes DocumentImportEvent event) {
|
||||||
|
|
||||||
|
|
@ -164,8 +163,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
documentImportService.logMessage("...CARGOSOFT_INVOICE_XML Import started: mandant.id=" + mandantID,
|
documentImportService.logMessage("...CARGOSOFT_INVOICE_XML Import started: mandant.id=" + mandantID, event);
|
||||||
event);
|
|
||||||
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
|
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
|
||||||
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
|
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
|
||||||
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
|
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
|
||||||
|
|
@ -218,8 +216,8 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
ftpClient.connect(ftpServer, ftpPort);
|
ftpClient.connect(ftpServer, ftpPort);
|
||||||
|
|
||||||
if (ftpClient.login(ftpUser, ftpPassword) == false) {
|
if (ftpClient.login(ftpUser, ftpPassword) == false) {
|
||||||
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
|
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
|
||||||
"FTP_ERROR", "FTP file transfer failed: login failed!");
|
"FTP file transfer failed: login failed!");
|
||||||
}
|
}
|
||||||
ftpClient.enterLocalPassiveMode();
|
ftpClient.enterLocalPassiveMode();
|
||||||
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
|
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
|
||||||
|
|
@ -227,8 +225,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
ftpClient.setControlEncoding("UTF-8");
|
ftpClient.setControlEncoding("UTF-8");
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
|
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR", e.getMessage());
|
||||||
"FTP_ERROR", e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ftpClient;
|
return ftpClient;
|
||||||
|
|
@ -236,7 +233,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method reads the working FTP directory and starts importing the files.
|
* Helper method reads the working FTP directory and starts importing the files.
|
||||||
*
|
*
|
||||||
* @param ftpClient
|
* @param ftpClient
|
||||||
* @param ftpPath
|
* @param ftpPath
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
|
|
@ -252,8 +249,8 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
// try to enter the working directory and read all files...
|
// try to enter the working directory and read all files...
|
||||||
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
|
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
|
||||||
if (bWorkingDir == false) {
|
if (bWorkingDir == false) {
|
||||||
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
|
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
|
||||||
"FTP_ERROR", "...failed to change into working directory: ");
|
"...failed to change into working directory: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
|
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
|
||||||
|
|
@ -301,10 +298,10 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
// "processed/");
|
// "processed/");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
} catch (AccessDeniedException | ProcessingErrorException | PluginException
|
} catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException
|
||||||
| ModelException | XPathExpressionException | TransformerException e) {
|
| XPathExpressionException | TransformerException e) {
|
||||||
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
|
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
|
||||||
"FTP_ERROR", e.getMessage());
|
e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
documentImportService.logMessage("..." + count + " new files imported.", event);
|
documentImportService.logMessage("..." + count + " new files imported.", event);
|
||||||
|
|
@ -315,8 +312,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
int r = ftpClient.getReplyCode();
|
int r = ftpClient.getReplyCode();
|
||||||
logger.severe("FTP ReplyCode=" + r);
|
logger.severe("FTP ReplyCode=" + r);
|
||||||
|
|
||||||
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
|
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR", e.getMessage());
|
||||||
"FTP_ERROR", e.getMessage());
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
// do logout....
|
// do logout....
|
||||||
|
|
@ -326,8 +322,8 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
ftpClient.disconnect();
|
ftpClient.disconnect();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
|
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
|
||||||
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
|
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
|
||||||
"FTP_ERROR", e.getMessage());
|
e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -335,8 +331,8 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
/**
|
/**
|
||||||
* Creates and processes a new workitem with a given xml information from the
|
* Creates and processes a new workitem with a given xml information from the
|
||||||
* fileData
|
* fileData
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws ModelException
|
* @throws ModelException
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
|
|
@ -346,9 +342,8 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
* @throws XPathExpressionException
|
* @throws XPathExpressionException
|
||||||
*/
|
*/
|
||||||
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
|
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
|
||||||
Map<String, List<String>> spacePosMappings)
|
Map<String, List<String>> spacePosMappings) throws AccessDeniedException, ProcessingErrorException,
|
||||||
throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException,
|
PluginException, ModelException, XPathExpressionException, TransformerException {
|
||||||
XPathExpressionException, TransformerException {
|
|
||||||
ItemCollection workitem = new ItemCollection();
|
ItemCollection workitem = new ItemCollection();
|
||||||
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
|
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
|
||||||
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
|
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
|
||||||
|
|
@ -377,11 +372,11 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
// invoice.rate
|
// invoice.rate
|
||||||
// invoice.base.amount
|
// invoice.base.amount
|
||||||
|
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Client/Codes/Code", workitem,
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Client/Codes/Code", workitem, "mandant.id",
|
||||||
"mandant.id", String.class);
|
String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceNumber",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceNumber", workitem, "invoice.number",
|
||||||
workitem, "invoice.number", String.class);
|
String.class);
|
||||||
|
|
||||||
// verify if invoice is already imported.
|
// verify if invoice is already imported.
|
||||||
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
|
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
|
||||||
|
|
@ -389,14 +384,14 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Codes/Code",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Codes/Code", workitem, "invoice.type",
|
||||||
workitem, "invoice.type", String.class);
|
String.class);
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Description",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Description", workitem,
|
||||||
workitem, "invoice.type.description", String.class);
|
"invoice.type.description", String.class);
|
||||||
|
|
||||||
// Rechnungssumme errechnen.....
|
// Rechnungssumme errechnen.....
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/NetAmount/Amount/Value",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/NetAmount/Amount/Value", workitem,
|
||||||
workitem, "invoice.total.net", Double.class);
|
"invoice.total.net", Double.class);
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VATAmount/Amount/Value",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VATAmount/Amount/Value",
|
||||||
workitem, "invoice.total.tax", Double.class);
|
workitem, "invoice.total.tax", Double.class);
|
||||||
if (!workitem.hasItem("invoice.total.tax")) {
|
if (!workitem.hasItem("invoice.total.tax")) {
|
||||||
|
|
@ -416,34 +411,33 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steuer
|
// Steuer
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VAT/VATRate",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VAT/VATRate", workitem,
|
||||||
workitem, "invoice.vatrate", Double.class);
|
"invoice.vatrate", Double.class);
|
||||||
|
|
||||||
// Booking Period
|
// Booking Period
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/BookingPeriod",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/BookingPeriod", workitem, "invoice.bookingperiod",
|
||||||
workitem, "invoice.bookingperiod", String.class);
|
String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceCurrency/Codes/Code",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceCurrency/Codes/Code", workitem,
|
||||||
workitem, "invoice.currency", String.class);
|
"invoice.currency", String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceDate",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceDate", workitem, "invoice.date", Date.class);
|
||||||
workitem, "invoice.date", Date.class);
|
|
||||||
|
|
||||||
readXMLValue(doc,
|
readXMLValue(doc,
|
||||||
"/Invoices/Invoice/InvoiceHeader/PaymentConditions/PaymentCondition/Codes/Code[@Type='cs']",
|
"/Invoices/Invoice/InvoiceHeader/PaymentConditions/PaymentCondition/Codes/Code[@Type='cs']",
|
||||||
workitem, "payment.term", String.class);
|
workitem, "payment.term", String.class);
|
||||||
|
|
||||||
// kostenstelle
|
// kostenstelle
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/CostUnit/Description",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/CostUnit/Description", workitem, "invoice.CostUnit",
|
||||||
workitem, "invoice.CostUnit", String.class);
|
String.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate", workitem, "invoice.duedate",
|
||||||
workitem, "invoice.duedate", Date.class);
|
Date.class);
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate", workitem, "invoice.reminder",
|
||||||
workitem, "invoice.reminder", Date.class);
|
Date.class);
|
||||||
|
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAddress/Codes/Code",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAddress/Codes/Code", workitem, "dbtr.number",
|
||||||
workitem, "dbtr.number", String.class);
|
String.class);
|
||||||
String dbtrNumber = workitem.getItemValueString("dbtr.number");
|
String dbtrNumber = workitem.getItemValueString("dbtr.number");
|
||||||
if (dbtrNumber.startsWith("K") || dbtrNumber.startsWith("D")) {
|
if (dbtrNumber.startsWith("K") || dbtrNumber.startsWith("D")) {
|
||||||
workitem.setItemValue("dbtr.number", dbtrNumber.substring(1));
|
workitem.setItemValue("dbtr.number", dbtrNumber.substring(1));
|
||||||
|
|
@ -487,17 +481,16 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
attacheFiles(doc, workitem);
|
attacheFiles(doc, workitem);
|
||||||
|
|
||||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||||
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
|
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "XML_ERROR", e.getMessage());
|
||||||
"XML_ERROR", e.getMessage());
|
|
||||||
}
|
}
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft ob die Rechnung eine Rückstellung ist also mit R1 bis R8 beginnt
|
* Prüft ob die Rechnung eine Rückstellung ist also mit R1 bis R8 beginnt
|
||||||
*
|
*
|
||||||
* ^R[1-8] .
|
* ^R[1-8] .
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -509,12 +502,11 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
/**
|
/**
|
||||||
* Reads a tag value from the xml tree and set the value into the given
|
* Reads a tag value from the xml tree and set the value into the given
|
||||||
* workitem.
|
* workitem.
|
||||||
*
|
*
|
||||||
* /Invoices/Invoice/InvoiceHeader/Client/Code
|
* /Invoices/Invoice/InvoiceHeader/Client/Code
|
||||||
*
|
*
|
||||||
* Beispiel Datum:
|
* Beispiel Datum: <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
|
||||||
* <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
|
*
|
||||||
*
|
|
||||||
* @param doc - xml doc
|
* @param doc - xml doc
|
||||||
* @param expression - xpath expression
|
* @param expression - xpath expression
|
||||||
* @param workitem
|
* @param workitem
|
||||||
|
|
@ -566,12 +558,10 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode die die ATC Nummer sucht und in das workitem feld
|
* Hilfsmethode die die ATC Nummer sucht und in das workitem feld
|
||||||
* invoice.atc.number einträgt.
|
* invoice.atc.number einträgt. Wir gehen davon aus, das wir über die ChildItems
|
||||||
* Wir gehen davon aus, das wir über die ChildItems diese aus dem billingtexts
|
* diese aus dem billingtexts schon ermittel haben. Es können mehrere ATC
|
||||||
* schon ermittel haben.
|
* nummern existieren. Diese werden in einer Liste gespeichert
|
||||||
* Es können mehrere ATC nummern existieren. Diese werden in einer Liste
|
*
|
||||||
* gespeichert
|
|
||||||
*
|
|
||||||
* @param doc
|
* @param doc
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
|
|
@ -592,19 +582,13 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the positions rows
|
* Reads the positions rows
|
||||||
*
|
*
|
||||||
* InvoiceRows/InvoiceRow
|
* InvoiceRows/InvoiceRow
|
||||||
*
|
*
|
||||||
* Each row has the following items:
|
* Each row has the following items: _childitems { datev.shzeichen=[H],
|
||||||
* _childitems {
|
* datev.kurs=[0.0], datev.basisumsatz=[0.0], datev.text=[R LA-PAP-2405-051],
|
||||||
* datev.shzeichen=[H],
|
* datev.konto=[3851], datev.umsatz=[3307.81], datev.wkz=[EUR]}}
|
||||||
* 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 doc - xml doc
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
|
|
@ -622,8 +606,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
XPathExpression netAmountExchangeRateExpr = xPath
|
XPathExpression netAmountExchangeRateExpr = xPath
|
||||||
.compile("InvoiceAmount/NetAmount/Amount/ExchangeRate/text()");
|
.compile("InvoiceAmount/NetAmount/Amount/ExchangeRate/text()");
|
||||||
|
|
||||||
XPathExpression netActivityTypeExpr = xPath
|
XPathExpression netActivityTypeExpr = xPath.compile("ActivityType/Codes/Code[@Type='cs']/text()");
|
||||||
.compile("ActivityType/Codes/Code[@Type='cs']/text()");
|
|
||||||
|
|
||||||
NodeList rowList = doc.getElementsByTagName("InvoiceRow");
|
NodeList rowList = doc.getElementsByTagName("InvoiceRow");
|
||||||
double _kurs = 0.0;
|
double _kurs = 0.0;
|
||||||
|
|
@ -679,7 +662,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* S/H Kennzeichen auflösen
|
* S/H Kennzeichen auflösen
|
||||||
*
|
*
|
||||||
* Bei G = Gutschrift oder SR = Stornorechnung müssen wir das vorzeichen ändern
|
* Bei G = Gutschrift oder SR = Stornorechnung müssen wir das vorzeichen ändern
|
||||||
* Invoice Type S/H
|
* Invoice Type S/H
|
||||||
*/
|
*/
|
||||||
|
|
@ -693,7 +676,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liste der BillingText-Elemente lesen....
|
* Liste der BillingText-Elemente lesen....
|
||||||
*
|
*
|
||||||
* und ggf. die ATC Nummer finden....
|
* und ggf. die ATC Nummer finden....
|
||||||
**/
|
**/
|
||||||
childItemCol.setItemValue("BillingCode", billingCode);
|
childItemCol.setItemValue("BillingCode", billingCode);
|
||||||
|
|
@ -732,14 +715,11 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G = Gutschrift
|
* G = Gutschrift SR = Stornorechnung GK = Sammelgutschrift SS = Sammelrechnung
|
||||||
* SR = Stornorechnung
|
* Storno
|
||||||
* 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
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean isGutschrift(ItemCollection workitem) {
|
private boolean isGutschrift(ItemCollection workitem) {
|
||||||
|
|
@ -748,10 +728,10 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method attache the pdf file and the XML file to the workitem.
|
* This method attache the pdf file and the XML file to the workitem. The method
|
||||||
* The method removes the file content first form the xml tree and attache the
|
* removes the file content first form the xml tree and attache the XML without
|
||||||
* XML without the pdf data.
|
* the pdf data.
|
||||||
*
|
*
|
||||||
* @throws XPathExpressionException
|
* @throws XPathExpressionException
|
||||||
* @throws TransformerException
|
* @throws TransformerException
|
||||||
*/
|
*/
|
||||||
|
|
@ -761,16 +741,16 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
XPathFactory xpathFactory = XPathFactory.newInstance();
|
XPathFactory xpathFactory = XPathFactory.newInstance();
|
||||||
XPath xpath = xpathFactory.newXPath();
|
XPath xpath = xpathFactory.newXPath();
|
||||||
// read filename and content....
|
// read filename and content....
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Filename",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Filename", workitem,
|
||||||
workitem, "import.filename", String.class);
|
"import.filename", String.class);
|
||||||
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Content",
|
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Content", workitem, "import.filedata",
|
||||||
workitem, "import.filedata", String.class);
|
String.class);
|
||||||
|
|
||||||
// attache the PDF file content
|
// attache the PDF file content
|
||||||
String fileDataString = workitem.getItemValueString("import.filedata");
|
String fileDataString = workitem.getItemValueString("import.filedata");
|
||||||
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
|
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
|
||||||
FileData fileData = new FileData(workitem.getItemValueString("import.filename"),
|
FileData fileData = new FileData(workitem.getItemValueString("import.filename"), decodedPDFData,
|
||||||
decodedPDFData, "application/pdf", null);
|
"application/pdf", null);
|
||||||
workitem.addFileData(fileData);
|
workitem.addFileData(fileData);
|
||||||
// remove the temp items..
|
// remove the temp items..
|
||||||
workitem.removeItem("import.filename");
|
workitem.removeItem("import.filename");
|
||||||
|
|
@ -804,7 +784,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft ob die Belegnummer schon existiert (importiert wurde)
|
* Prüft ob die Belegnummer schon existiert (importiert wurde)
|
||||||
*
|
*
|
||||||
* @param belegNummer
|
* @param belegNummer
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -828,7 +808,7 @@ public class CargosoftXMLInvoiceImportService {
|
||||||
* Diese Method sucht einen Debitor.
|
* Diese Method sucht einen Debitor.
|
||||||
* <p>
|
* <p>
|
||||||
* Diese Methode erwartet das führende D
|
* Diese Methode erwartet das führende D
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
public ItemCollection findDebitor(String dbtrNumber) throws PluginException {
|
public ItemCollection findDebitor(String dbtrNumber) throws PluginException {
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ package com.alexanderlogistics.zoho;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for JSON deserialization
|
* Helper class for JSON deserialization
|
||||||
*
|
*
|
||||||
* If the request is successful, you would receive the following:
|
* If the request is successful, you would receive the following:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
{
|
{
|
||||||
"access_token": "{access_token}",
|
"access_token": "{access_token}",
|
||||||
|
|
|
||||||
|
|
@ -42,336 +42,306 @@ import jakarta.json.bind.JsonbConfig;
|
||||||
* Der ZohoAPIService stellt methoden für den Zugriff auf die Zoho API bereit.
|
* Der ZohoAPIService stellt methoden für den Zugriff auf die Zoho API bereit.
|
||||||
*/
|
*/
|
||||||
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||||
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
||||||
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||||
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
|
||||||
@Singleton
|
@Singleton
|
||||||
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
||||||
public class ZohoAPIService {
|
public class ZohoAPIService {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
|
private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
|
||||||
private static final String ZOHO_API_BASE_URL = "https://www.zohoapis.eu/books/v3/";
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ZohoOAuthManager zohoOAuthManager;
|
ZohoOAuthManager zohoOAuthManager;
|
||||||
|
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private Jsonb jsonb;
|
private Jsonb jsonb;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
void init() {
|
void init() {
|
||||||
this.httpClient = HttpClient.newBuilder()
|
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||||
.connectTimeout(Duration.ofSeconds(10))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
JsonbConfig config = new JsonbConfig()
|
JsonbConfig config = new JsonbConfig().withDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||||
.withDateFormat("yyyy-MM-dd", Locale.getDefault())
|
.setProperty("jsonb.fail-on-unknown-properties", false); // Ignoriert unbekannte Felder
|
||||||
.setProperty("jsonb.fail-on-unknown-properties", false); // Ignoriert unbekannte Felder
|
this.jsonb = JsonbBuilder.create(config);
|
||||||
this.jsonb = JsonbBuilder.create(config);
|
}
|
||||||
|
|
||||||
|
public String findContactIDByCompanyName(String companyName, String accessToken) throws PluginException {
|
||||||
|
|
||||||
|
// Print JSON to console for verification
|
||||||
|
logger.info("├── Zoho lookup contact '" + companyName + "'...");
|
||||||
|
try {
|
||||||
|
// https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
|
||||||
|
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))
|
||||||
|
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
||||||
|
.header("Content-Type", "application/json").GET().build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
||||||
|
// Print response details to console
|
||||||
|
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 find Contacts - Status code: " + response.statusCode() + ", Response: "
|
||||||
|
+ response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
ZohoContactFindResponse contactsResponse = jsonb.fromJson(response.body(), ZohoContactFindResponse.class);
|
||||||
|
|
||||||
|
if (contactsResponse != null && contactsResponse.getContacts() != null) {
|
||||||
|
// Durchsuche die Ergebnisse nach exakter Übereinstimmung
|
||||||
|
for (ZohoContact contact : contactsResponse.getContacts()) {
|
||||||
|
if (companyName.equalsIgnoreCase(contact.getCompanyName())) {
|
||||||
|
logger.info("│ ├── contactID= " + contact.getContactId());
|
||||||
|
return contact.getContactId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error", "Failed to find contacts", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String findContactIDByCompanyName(String companyName, String accessToken) throws PluginException {
|
}
|
||||||
|
|
||||||
// Print JSON to console for verification
|
/**
|
||||||
logger.info("├── Zoho lookup contact '" + companyName + "'...");
|
* Exports an invocie document
|
||||||
try {
|
*
|
||||||
// https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
|
* @see https://www.zoho.com/books/api/v3/invoices/#create-an-invoice
|
||||||
String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
|
*
|
||||||
+ zohoOAuthManager.getOrganization() + "&company_name="
|
* @param invoice
|
||||||
+ URLEncoder.encode(companyName, StandardCharsets.UTF_8);
|
* @throws PluginException
|
||||||
logger.fine("│ ├── uri= " + uri);
|
*/
|
||||||
logger.fine("│ ├── accessToken=" + accessToken);
|
public ZohoInvoice exportInvoice(ItemCollection invoice, List<FileData> files) throws PluginException {
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
String accessToken = zohoOAuthManager.getValidAccessToken();
|
||||||
.uri(URI.create(uri))
|
logger.info("├── Zoho Export Invoice " + invoice.getItemValueString("invoice.number") + "...");
|
||||||
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(
|
|
||||||
request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
// Print response details to console
|
|
||||||
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 find Contacts - Status code: " + response.statusCode() +
|
|
||||||
", Response: " + response.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
ZohoContactFindResponse contactsResponse = jsonb.fromJson(response.body(),
|
|
||||||
ZohoContactFindResponse.class);
|
|
||||||
|
|
||||||
if (contactsResponse != null && contactsResponse.getContacts() != null) {
|
|
||||||
// Durchsuche die Ergebnisse nach exakter Übereinstimmung
|
|
||||||
for (ZohoContact contact : contactsResponse.getContacts()) {
|
|
||||||
if (companyName.equalsIgnoreCase(contact.getCompanyName())) {
|
|
||||||
logger.info("│ ├── contactID= " + contact.getContactId());
|
|
||||||
return contact.getContactId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Failed to find contacts", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// first lookup contact!
|
||||||
|
String contactID = "";
|
||||||
|
contactID = findContactIDByCompanyName(invoice.getItemValueString("dbtr.name"), accessToken);
|
||||||
|
if (contactID == null) {
|
||||||
|
logger.info("│ ├── contact not found");
|
||||||
|
ZohoContact contact = createContact(invoice.getItemValueString("dbtr.name"), accessToken);
|
||||||
|
contactID = contact.getContactId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
||||||
* Exports an invocie document
|
ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID, accessToken);
|
||||||
*
|
|
||||||
* @see https://www.zoho.com/books/api/v3/invoices/#create-an-invoice
|
|
||||||
*
|
|
||||||
* @param invoice
|
|
||||||
* @throws PluginException
|
|
||||||
*/
|
|
||||||
public ZohoInvoice exportInvoice(ItemCollection invoice, List<FileData> files) throws PluginException {
|
|
||||||
String accessToken = zohoOAuthManager.getValidAccessToken();
|
|
||||||
logger.info("├── Zoho Export Invoice " + invoice.getItemValueString("invoice.number") + "...");
|
|
||||||
|
|
||||||
// first lookup contact!
|
try {
|
||||||
String contactID = "";
|
String requestBody = jsonb.toJson(zohoInvoice);
|
||||||
contactID = findContactIDByCompanyName(invoice.getItemValueString("dbtr.name"), accessToken);
|
|
||||||
if (contactID == null) {
|
// Print JSON to console for verification
|
||||||
logger.info("│ ├── contact not found");
|
logger.fine("├── Zoho Invoice JSON Request...");
|
||||||
ZohoContact contact = createContact(invoice.getItemValueString("dbtr.name"), accessToken);
|
logger.fine("│ ├── " + requestBody);
|
||||||
contactID = contact.getContactId();
|
|
||||||
|
// https://www.zohoapis.com/books/v3/invoices?organization_id=10234695'
|
||||||
|
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))
|
||||||
|
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
||||||
|
.header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
||||||
|
// Print response details to console
|
||||||
|
logger.fine("├── Zoho Response:");
|
||||||
|
logger.fine("│ ├── Status Code: " + response.statusCode());
|
||||||
|
|
||||||
|
if (response.statusCode() >= 300) {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
|
"Failed to create invoice. Status code: " + response.statusCode() + ", Response: "
|
||||||
|
+ response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erfolgreiche Erstellung
|
||||||
|
String bodyContent = response.body();
|
||||||
|
logger.fine("│ ├── Response Body: " + bodyContent);
|
||||||
|
|
||||||
|
System.out.print(bodyContent);
|
||||||
|
ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent, ZohoInvoiceCreateResponse.class);
|
||||||
|
|
||||||
|
logger.fine("│ ├── OK - customerID=" + createResponse.getInvoice().getCustomerId());
|
||||||
|
logger.info("│ ├── OK - invoiceID=" + createResponse.getInvoice().getInvoiceId());
|
||||||
|
|
||||||
|
if (createResponse != null) {
|
||||||
|
zohoInvoice = createResponse.getInvoice();
|
||||||
|
|
||||||
|
// now add attachments (optional)
|
||||||
|
if (files != null) {
|
||||||
|
for (FileData file : files) {
|
||||||
|
attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices", accessToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
logger.info("│ ├── Invoice Export successful.");
|
||||||
ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID, accessToken);
|
|
||||||
|
|
||||||
try {
|
|
||||||
String requestBody = jsonb.toJson(zohoInvoice);
|
|
||||||
|
|
||||||
// Print JSON to console for verification
|
|
||||||
logger.fine("├── Zoho Invoice JSON Request...");
|
|
||||||
logger.fine("│ ├── " + requestBody);
|
|
||||||
|
|
||||||
// https://www.zohoapis.com/books/v3/invoices?organization_id=10234695'
|
|
||||||
String uri = ZOHO_API_BASE_URL + "invoices?organization_id="
|
|
||||||
+ zohoOAuthManager.getOrganization();
|
|
||||||
logger.fine("│ ├── uri= " + uri);
|
|
||||||
logger.fine("│ ├── accessToken=" + accessToken);
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(uri))
|
|
||||||
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(
|
|
||||||
request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
// Print response details to console
|
|
||||||
logger.fine("├── Zoho Response:");
|
|
||||||
logger.fine("│ ├── Status Code: " + response.statusCode());
|
|
||||||
|
|
||||||
if (response.statusCode() >= 300) {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Failed to create invoice. Status code: " + response.statusCode() +
|
|
||||||
", Response: " + response.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erfolgreiche Erstellung
|
|
||||||
String bodyContent = response.body();
|
|
||||||
logger.fine("│ ├── Response Body: " + bodyContent);
|
|
||||||
|
|
||||||
System.out.print(bodyContent);
|
|
||||||
ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent,
|
|
||||||
ZohoInvoiceCreateResponse.class);
|
|
||||||
|
|
||||||
logger.fine("│ ├── OK - customerID=" + createResponse.getInvoice().getCustomerId());
|
|
||||||
logger.info("│ ├── OK - invoiceID=" + createResponse.getInvoice().getInvoiceId());
|
|
||||||
|
|
||||||
if (createResponse != null) {
|
|
||||||
zohoInvoice = createResponse.getInvoice();
|
|
||||||
|
|
||||||
// now add attachments (optional)
|
|
||||||
if (files != null) {
|
|
||||||
for (FileData file : files) {
|
|
||||||
attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices",
|
|
||||||
accessToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("│ ├── Invoice Export successful.");
|
|
||||||
return zohoInvoice;
|
|
||||||
} else {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Failed to export invoice to Zoho: unable to resolve response");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Failed to export invoice to Zoho: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Erstellt einen neuen Contact in Zoho Books
|
|
||||||
*
|
|
||||||
* @param companyName Der Firmenname für den neuen Contact
|
|
||||||
* @return Der erstellte ZohoContact mit contact_id
|
|
||||||
* @throws PluginException Wenn der API-Aufruf fehlschlägt
|
|
||||||
*/
|
|
||||||
public ZohoContact createContact(String companyName, String accessToken) throws PluginException {
|
|
||||||
logger.info("├── Zoho create contact '" + companyName + "'...");
|
|
||||||
try {
|
|
||||||
// Contact-DTO vorbereiten
|
|
||||||
ZohoContact newContact = new ZohoContact();
|
|
||||||
newContact.setContactName(companyName); // Wir verwenden den Firmennamen auch als Contact Name
|
|
||||||
newContact.setCompanyName(companyName);
|
|
||||||
|
|
||||||
// JSON serialisieren
|
|
||||||
String requestBody = jsonb.toJson(newContact);
|
|
||||||
logger.fine("│ ├── " + requestBody);
|
|
||||||
String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
|
|
||||||
+ zohoOAuthManager.getOrganization();
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(uri))
|
|
||||||
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erfolgreiche Erstellung
|
|
||||||
ZohoContactCreateResponse createResponse = jsonb.fromJson(response.body(),
|
|
||||||
ZohoContactCreateResponse.class);
|
|
||||||
if (createResponse != null) {
|
|
||||||
logger.info("│ ├── OK - contactID=" + createResponse.getContact().getContactId());
|
|
||||||
return createResponse.getContact();
|
|
||||||
} else {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Response could not be resolved!");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Failed to create contact: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID, String accessToken)
|
|
||||||
throws PluginException {
|
|
||||||
|
|
||||||
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.setDate(
|
|
||||||
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(),
|
|
||||||
ZoneId.systemDefault()));
|
|
||||||
|
|
||||||
zohoInvoice.setDueDate(
|
|
||||||
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 -> {
|
|
||||||
ItemCollection itemCol = (ItemCollection) item;
|
|
||||||
ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
|
|
||||||
lineItem.setName(itemCol.getItemValueString("datev.text"));
|
|
||||||
lineItem.setDescription(itemCol.getItemValueString("billingtext"));
|
|
||||||
lineItem.setRate(itemCol.getItemValueDouble("datev.umsatz"));
|
|
||||||
lineItem.setQuantity(1);
|
|
||||||
return lineItem;
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
zohoInvoice.setLineItems(lineItems);
|
|
||||||
return zohoInvoice;
|
return zohoInvoice;
|
||||||
|
} else {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
|
"Failed to export invoice to Zoho: unable to resolve response");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
|
"Failed to export invoice to Zoho: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
}
|
||||||
* This method adds an attachment to an invoice
|
|
||||||
*
|
|
||||||
* @param invoiceId The Zoho invoice ID
|
|
||||||
* @param file The FileData object containing the attachment
|
|
||||||
* @param uriPattern The API endpoint pattern (e.g., "invoices")
|
|
||||||
* @param accessToken The OAuth access token
|
|
||||||
* @throws PluginException If the API call fails
|
|
||||||
*/
|
|
||||||
public void attacheFileData(String invoiceId, FileData file, String uriPattern, String accessToken)
|
|
||||||
throws PluginException {
|
|
||||||
String uri = ZOHO_API_BASE_URL + uriPattern + "/" + invoiceId + "/attachment" +
|
|
||||||
"?organization_id=" + zohoOAuthManager.getOrganization();
|
|
||||||
|
|
||||||
logger.info("│ ├── add attachment '" + file.getName() + "'...");
|
/**
|
||||||
logger.fine("│ ├── ...uri: " + uri + "...");
|
* Erstellt einen neuen Contact in Zoho Books
|
||||||
|
*
|
||||||
|
* @param companyName Der Firmenname für den neuen Contact
|
||||||
|
* @return Der erstellte ZohoContact mit contact_id
|
||||||
|
* @throws PluginException Wenn der API-Aufruf fehlschlägt
|
||||||
|
*/
|
||||||
|
public ZohoContact createContact(String companyName, String accessToken) throws PluginException {
|
||||||
|
logger.info("├── Zoho create contact '" + companyName + "'...");
|
||||||
|
try {
|
||||||
|
// Contact-DTO vorbereiten
|
||||||
|
ZohoContact newContact = new ZohoContact();
|
||||||
|
newContact.setContactName(companyName); // Wir verwenden den Firmennamen auch als Contact Name
|
||||||
|
newContact.setCompanyName(companyName);
|
||||||
|
|
||||||
try {
|
// JSON serialisieren
|
||||||
// Generate a unique boundary
|
String requestBody = jsonb.toJson(newContact);
|
||||||
String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
|
logger.fine("│ ├── " + requestBody);
|
||||||
|
String uri = zohoOAuthManager.getBaseURI() + "contacts?organization_id="
|
||||||
|
+ zohoOAuthManager.getOrganization();
|
||||||
|
|
||||||
// Build multipart request body
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
|
||||||
byte[] header = ("--" + boundary + "\r\n" +
|
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
||||||
"Content-Disposition: form-data; name=\"attachment\"; filename=\""
|
.header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody))
|
||||||
+ file.getName() + "\"\r\n" +
|
.build();
|
||||||
"Content-Type: " + file.getContentType() + "\r\n\r\n")
|
|
||||||
.getBytes(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
byte[] footer = ("\r\n--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8);
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
logger.fine("│ ├── content size=" + file.getContent().length);
|
// Erfolgreiche Erstellung
|
||||||
HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers.ofByteArrays(
|
ZohoContactCreateResponse createResponse = jsonb.fromJson(response.body(), ZohoContactCreateResponse.class);
|
||||||
Arrays.asList(header, file.getContent(), footer));
|
if (createResponse != null) {
|
||||||
|
logger.info("│ ├── OK - contactID=" + createResponse.getContact().getContactId());
|
||||||
|
return createResponse.getContact();
|
||||||
|
} else {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
|
"Response could not be resolved!");
|
||||||
|
}
|
||||||
|
|
||||||
// Create and send the request
|
} catch (IOException | InterruptedException e) {
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
.uri(URI.create(uri))
|
"Failed to create contact: " + e.getMessage(), e);
|
||||||
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
|
||||||
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
|
|
||||||
.POST(bodyPublisher)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
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 add attachment. Status code: " + response.statusCode() +
|
|
||||||
", Response: " + response.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("│ ├── OK - Attachment added successfully");
|
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Failed to add attachment: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID, String accessToken)
|
||||||
|
throws PluginException {
|
||||||
|
|
||||||
|
ZohoInvoice zohoInvoice = new ZohoInvoice();
|
||||||
|
// Basisinformationen
|
||||||
|
|
||||||
|
zohoInvoice.setInvoiceNumber(invoice.getItemValueString("invoice.number"));
|
||||||
|
zohoInvoice.setDate(
|
||||||
|
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault()));
|
||||||
|
|
||||||
|
zohoInvoice.setDueDate(
|
||||||
|
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 -> {
|
||||||
|
ItemCollection itemCol = (ItemCollection) item;
|
||||||
|
ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
|
||||||
|
lineItem.setName(itemCol.getItemValueString("datev.text"));
|
||||||
|
lineItem.setDescription(itemCol.getItemValueString("billingtext"));
|
||||||
|
lineItem.setRate(itemCol.getItemValueDouble("datev.umsatz"));
|
||||||
|
lineItem.setQuantity(1);
|
||||||
|
return lineItem;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
zohoInvoice.setLineItems(lineItems);
|
||||||
|
return zohoInvoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method adds an attachment to an invoice
|
||||||
|
*
|
||||||
|
* @param invoiceId The Zoho invoice ID
|
||||||
|
* @param file The FileData object containing the attachment
|
||||||
|
* @param uriPattern The API endpoint pattern (e.g., "invoices")
|
||||||
|
* @param accessToken The OAuth access token
|
||||||
|
* @throws PluginException If the API call fails
|
||||||
|
*/
|
||||||
|
public void attacheFileData(String invoiceId, FileData file, String uriPattern, String accessToken)
|
||||||
|
throws PluginException {
|
||||||
|
String uri = zohoOAuthManager.getBaseURI() + uriPattern + "/" + //
|
||||||
|
invoiceId + //
|
||||||
|
"/attachment" + //
|
||||||
|
"?organization_id=" + zohoOAuthManager.getOrganization();
|
||||||
|
|
||||||
|
logger.info("│ ├── add attachment '" + file.getName() + "'...");
|
||||||
|
logger.fine("│ ├── ...uri: " + uri + "...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Generate a unique boundary
|
||||||
|
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[] 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));
|
||||||
|
|
||||||
|
// Create and send the request
|
||||||
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
|
||||||
|
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
||||||
|
.header("Content-Type", "multipart/form-data; boundary=" + boundary).POST(bodyPublisher).build();
|
||||||
|
|
||||||
|
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 add attachment. Status code: " + response.statusCode() + ", Response: "
|
||||||
|
+ response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("│ ├── OK - Attachment added successfully");
|
||||||
|
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
|
"Failed to add attachment: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,26 @@ package com.alexanderlogistics.zoho;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Imixs Workflow Technology
|
* Imixs Workflow Technology
|
||||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - initial API and implementation
|
* Imixs Software Solutions GmbH - initial API and implementation
|
||||||
* Ralph Soika
|
* Ralph Soika
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
@ -35,54 +35,54 @@ import jakarta.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Der ZohoController ist für das Admin Interface um Access Tokens zu erzeugen.
|
* Der ZohoController ist für das Admin Interface um Access Tokens zu erzeugen.
|
||||||
*
|
*
|
||||||
* @see admin/zoho.xhml
|
* @see admin/zoho.xhml
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Named("zohoController")
|
@Named("zohoController")
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class ZohoController extends ConfigController {
|
public class ZohoController extends ConfigController {
|
||||||
|
|
||||||
public static final String ZOHO_CONFIGURATION = "ZOHO_CONFIGURATION";
|
public static final String ZOHO_CONFIGURATION = "ZOHO_CONFIGURATION";
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(ZohoController.class.getName());
|
private static Logger logger = Logger.getLogger(ZohoController.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ZohoOAuthManager zohoOAuthManager;
|
ZohoOAuthManager zohoOAuthManager;
|
||||||
|
|
||||||
public ZohoController() {
|
public ZohoController() {
|
||||||
super();
|
super();
|
||||||
setName(ZOHO_CONFIGURATION);
|
setName(ZOHO_CONFIGURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ruft zohoOAuhtManager.updateToken auf
|
* Ruft zohoOAuhtManager.updateToken auf
|
||||||
*/
|
*/
|
||||||
public void updateAccessToken() {
|
public void updateAccessToken() {
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
zohoOAuthManager.updateTokens(this.getWorkitem().getItemValueString("zoho.code"));
|
zohoOAuthManager.updateTokens(this.getWorkitem().getItemValueString("zoho.code"));
|
||||||
} catch (PluginException e) {
|
} catch (PluginException e) {
|
||||||
String message = "Failed to generate token: " + e.getMessage();
|
String message = "Failed to generate token: " + e.getMessage();
|
||||||
logger.warning(message);
|
logger.warning(message);
|
||||||
this.getWorkitem().setItemValue("message", message);
|
this.getWorkitem().setItemValue("message", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ruft zohoOAuhtManager.refreshToken auf
|
* Ruft zohoOAuhtManager.refreshToken auf
|
||||||
*/
|
*/
|
||||||
public void refreshAccessToken() {
|
public void refreshAccessToken() {
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
zohoOAuthManager.refreshAccessToken();
|
zohoOAuthManager.refreshAccessToken();
|
||||||
} catch (PluginException e) {
|
} catch (PluginException e) {
|
||||||
String message = "Failed to refresh token: " + e.getMessage();
|
String message = "Failed to refresh token: " + e.getMessage();
|
||||||
logger.warning(message);
|
logger.warning(message);
|
||||||
this.getWorkitem().setItemValue("message", message);
|
this.getWorkitem().setItemValue("message", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import jakarta.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This adapter exports the invoice data to zoho
|
* This adapter exports the invoice data to zoho
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
|
|
@ -44,7 +44,7 @@ public class ZohoExportAdapter implements SignalAdapter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method calls the zoho api
|
* This method calls the zoho api
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
/*
|
/*
|
||||||
* Imixs-Workflow
|
* Imixs-Workflow
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
* Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
|
||||||
* http://www.imixs.com
|
* http://www.imixs.com
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You can receive a copy of the GNU General Public
|
* You can receive a copy of the GNU General Public
|
||||||
* License at http://www.gnu.org/licenses/gpl.html
|
* License at http://www.gnu.org/licenses/gpl.html
|
||||||
*
|
*
|
||||||
* Project:
|
* Project:
|
||||||
* https://www.imixs.org
|
* https://www.imixs.org
|
||||||
* https://github.com/imixs/imixs-workflow
|
* https://github.com/imixs/imixs-workflow
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Imixs Software Solutions GmbH - Project Management
|
* Imixs Software Solutions GmbH - Project Management
|
||||||
* Ralph Soika - Software Developer
|
* Ralph Soika - Software Developer
|
||||||
*/
|
*/
|
||||||
|
|
@ -45,20 +45,20 @@ import jakarta.ws.rs.core.MediaType;
|
||||||
/**
|
/**
|
||||||
* Dieser API Endpoint dient dazu über zoho einen sogenannten Grant Token zu
|
* Dieser API Endpoint dient dazu über zoho einen sogenannten Grant Token zu
|
||||||
* erhalten.
|
* erhalten.
|
||||||
*
|
*
|
||||||
* https://www.zoho.com/books/api/v3/oauth/
|
* https://www.zoho.com/books/api/v3/oauth/
|
||||||
*
|
*
|
||||||
* Der Service wird aktuell nicht benötigt, das wir sogenannte Zoho Self-Clients
|
* Der Service wird aktuell nicht benötigt, das wir sogenannte Zoho Self-Clients
|
||||||
* verwenden!
|
* verwenden!
|
||||||
*
|
*
|
||||||
* Der Service stellt im Grunde nur eine Callback URL für einen normalen Zoho
|
* 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
|
* Client ein. Also wenn jemand einen solchen Token über den Browser anfordert.
|
||||||
* anfordert. Der URL muss dann odrt als CallBack URL angegeben sein!
|
* Der URL muss dann odrt als CallBack URL angegeben sein!
|
||||||
*
|
*
|
||||||
* Beispiel:
|
* Beispiel:
|
||||||
*
|
*
|
||||||
* https://accounts.zoho.com/oauth/v2/auth?scope=ZohoBooks.invoices.CREATE,ZohoBooks.invoices.READ,ZohoBooks.invoices.UPDATE,ZohoBooks.invoices.DELETE&client_id=1000.NLTM2KUEHI696MSLGEIANATVGGX7IN&state=testing&response_type=code&redirect_uri=https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant
|
* https://accounts.zoho.com/oauth/v2/auth?scope=ZohoBooks.invoices.CREATE,ZohoBooks.invoices.READ,ZohoBooks.invoices.UPDATE,ZohoBooks.invoices.DELETE&client_id=1000.NLTM2KUEHI696MSLGEIANATVGGX7IN&state=testing&response_type=code&redirect_uri=https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant
|
||||||
*
|
*
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
|
|
@ -85,15 +85,14 @@ public class ZohoOAuthCallbackService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive Grant Code.
|
* Receive Grant Code.
|
||||||
*
|
*
|
||||||
* The expected query params look like this:
|
* The expected query params look like this:
|
||||||
*
|
*
|
||||||
* state=testing
|
* state=testing
|
||||||
* code=1000.c27802b99c007ad8db93a5a7291cb15a.8cb60b6a51df13ea627ef3ac7c2e4791
|
* code=1000.c27802b99c007ad8db93a5a7291cb15a.8cb60b6a51df13ea627ef3ac7c2e4791
|
||||||
* location=eu
|
* location=eu accounts-server=https%3A%2F%2Faccounts.zoho.eu
|
||||||
* accounts-server=https%3A%2F%2Faccounts.zoho.eu
|
*
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param workflowgroup
|
* @param workflowgroup
|
||||||
* @param task
|
* @param task
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -102,11 +101,8 @@ public class ZohoOAuthCallbackService {
|
||||||
@GET
|
@GET
|
||||||
@Path("/grant")
|
@Path("/grant")
|
||||||
@Produces({ MediaType.TEXT_HTML })
|
@Produces({ MediaType.TEXT_HTML })
|
||||||
public String getGrantToken(
|
public String getGrantToken(@QueryParam("state") String state, @QueryParam("code") String code,
|
||||||
@QueryParam("state") String state,
|
@QueryParam("location") String location, @QueryParam("accounts-server") String accountsServer)
|
||||||
@QueryParam("code") String code,
|
|
||||||
@QueryParam("location") String location,
|
|
||||||
@QueryParam("accounts-server") String accountsServer)
|
|
||||||
throws QueryException {
|
throws QueryException {
|
||||||
|
|
||||||
logger.info("├── Receive Grant Token from Zoho");
|
logger.info("├── Receive Grant Token from Zoho");
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ import jakarta.json.bind.JsonbBuilder;
|
||||||
/**
|
/**
|
||||||
* Der ZohoOAuthManager stellt Methoden bereit um einen Access Token zu
|
* Der ZohoOAuthManager stellt Methoden bereit um einen Access Token zu
|
||||||
* erstellen.
|
* erstellen.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
||||||
|
|
@ -47,9 +47,7 @@ public class ZohoOAuthManager {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
void init() {
|
void init() {
|
||||||
this.httpClient = HttpClient.newBuilder()
|
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||||
.connectTimeout(Duration.ofSeconds(10))
|
|
||||||
.build();
|
|
||||||
this.jsonb = JsonbBuilder.create();
|
this.jsonb = JsonbBuilder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +55,7 @@ public class ZohoOAuthManager {
|
||||||
* Gibt den aktuellen Access Token zurück. Falls dieser expired ist wird
|
* Gibt den aktuellen Access Token zurück. Falls dieser expired ist wird
|
||||||
* automatisch ein refresh durchgeführt. Somit liefert die Methode immer einen
|
* automatisch ein refresh durchgeführt. Somit liefert die Methode immer einen
|
||||||
* gültigen token.
|
* gültigen token.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -87,14 +85,26 @@ public class ZohoOAuthManager {
|
||||||
return null;
|
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
|
* Step 3: Generate Access and Refresh Token
|
||||||
*
|
*
|
||||||
* After getting code from the GrantService we make a POST request
|
* After getting code from the GrantService we make a POST request
|
||||||
*
|
*
|
||||||
* See description: https://www.zoho.com/books/api/v3/oauth/
|
* See description: https://www.zoho.com/books/api/v3/oauth/
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param code
|
* @param code
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -107,24 +117,21 @@ public class ZohoOAuthManager {
|
||||||
|
|
||||||
String clientID = zohoConfig.getItemValueString("zoho.clientid");
|
String clientID = zohoConfig.getItemValueString("zoho.clientid");
|
||||||
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
|
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
|
||||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
|
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
|
||||||
"?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
||||||
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
"&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
|
||||||
"&redirect_uri=" + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
|
||||||
"&grant_type=authorization_code";
|
|
||||||
|
|
||||||
logger.fine("│ ├── Request URI=" + requestUrl);
|
logger.fine("│ ├── Request URI=" + requestUrl);
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
|
||||||
.uri(URI.create(requestUrl))
|
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
response = httpClient.send(request,
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
logger.fine("│ ├── Response statusCode=" + response.statusCode());
|
logger.fine("│ ├── Response statusCode=" + response.statusCode());
|
||||||
if (response.statusCode() == 200) {
|
if (response.statusCode() == 200) {
|
||||||
|
|
@ -132,29 +139,26 @@ public class ZohoOAuthManager {
|
||||||
logger.fine("│ ├── Response Body=" + response.body());
|
logger.fine("│ ├── Response Body=" + response.body());
|
||||||
|
|
||||||
if (response.body().contains("error")) {
|
if (response.body().contains("error")) {
|
||||||
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
|
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
|
||||||
ZohoOAuthManager.ERROR_CONFIG,
|
|
||||||
"Ungültiger Access Code!");
|
"Ungültiger Access Code!");
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
|
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
|
||||||
TokenResponse.class);
|
|
||||||
saveTokenData(zohoConfig, tokenResponse);
|
saveTokenData(zohoConfig, tokenResponse);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Failed to get tokens: " +
|
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
|
||||||
response.statusCode() + " - " + response.body());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
|
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
|
||||||
ZohoOAuthManager.ERROR_CONFIG, "Unable to resolve access tokens: " + e.getMessage());
|
"Unable to resolve access tokens: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method updates the Access Token based on the current Refresh Token
|
* This method updates the Access Token based on the current Refresh Token
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
|
|
@ -168,26 +172,21 @@ public class ZohoOAuthManager {
|
||||||
|
|
||||||
String refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
|
String refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
|
||||||
try {
|
try {
|
||||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
|
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?refresh_token="
|
||||||
"?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) + "&client_id="
|
||||||
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
"&client_secret=" + URLEncoder.encode(clientSecret,
|
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=refresh_token";
|
||||||
StandardCharsets.UTF_8)
|
|
||||||
+
|
|
||||||
"&grant_type=refresh_token";
|
|
||||||
|
|
||||||
logger.fine("│ ├── Request URI=" + requestUrl);
|
logger.fine("│ ├── Request URI=" + requestUrl);
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
|
||||||
.uri(URI.create(requestUrl))
|
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
|
|
||||||
response = httpClient.send(request,
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
logger.fine("│ ├── Response statusCode=" + response.statusCode());
|
logger.fine("│ ├── Response statusCode=" + response.statusCode());
|
||||||
if (response.statusCode() == 200) {
|
if (response.statusCode() == 200) {
|
||||||
|
|
@ -195,25 +194,23 @@ public class ZohoOAuthManager {
|
||||||
// 1. Response-Logging für Debugging
|
// 1. Response-Logging für Debugging
|
||||||
logger.fine("│ ├── Response Body=" + response.body());
|
logger.fine("│ ├── Response Body=" + response.body());
|
||||||
|
|
||||||
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
|
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
|
||||||
TokenResponse.class);
|
|
||||||
saveTokenData(zohoConfig, tokenResponse);
|
saveTokenData(zohoConfig, tokenResponse);
|
||||||
return zohoConfig.getItemValueString("zoho.accessToken");
|
return zohoConfig.getItemValueString("zoho.accessToken");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Failed to get tokens: " +
|
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
|
||||||
response.statusCode() + " - " + response.body());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
|
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
|
||||||
ZohoOAuthManager.ERROR_CONFIG, "Unable to refresh access tokens: " + e.getMessage());
|
"Unable to refresh access tokens: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to update the config itemcolleciton based on a tokenResponse
|
* Helper method to update the config itemcolleciton based on a tokenResponse
|
||||||
*
|
*
|
||||||
* @param zohoConfig
|
* @param zohoConfig
|
||||||
* @param tokenResponse
|
* @param tokenResponse
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,42 @@
|
||||||
package com.alexanderlogistics.zoho.dto;
|
package com.alexanderlogistics.zoho.dto;
|
||||||
|
|
||||||
public class ZohoInvoiceItem {
|
public class ZohoInvoiceItem {
|
||||||
private String name;
|
private String name;
|
||||||
private String description;
|
private String description;
|
||||||
private double rate;
|
private double rate;
|
||||||
private int quantity;
|
private int quantity;
|
||||||
|
|
||||||
// Getter und Setter
|
// Getter und Setter
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getRate() {
|
public double getRate() {
|
||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRate(double rate) {
|
public void setRate(double rate) {
|
||||||
this.rate = rate;
|
this.rate = rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getQuantity() {
|
public int getQuantity() {
|
||||||
return quantity;
|
return quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQuantity(int quantity) {
|
public void setQuantity(int quantity) {
|
||||||
this.quantity = quantity;
|
this.quantity = quantity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ import jakarta.inject.Named;
|
||||||
* The controller implements a caching mechanism to avoid repeated calls for new
|
* The controller implements a caching mechanism to avoid repeated calls for new
|
||||||
* analytic values. If the analytic value is already stored in the current
|
* analytic values. If the analytic value is already stored in the current
|
||||||
* workitem, no new value will be fired.
|
* workitem, no new value will be fired.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -33,150 +33,149 @@ import jakarta.inject.Named;
|
||||||
@ConversationScoped
|
@ConversationScoped
|
||||||
public class AnalyticController implements Serializable {
|
public class AnalyticController implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
|
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected Event<AnalyticEvent> analyticEvents;
|
protected Event<AnalyticEvent> analyticEvents;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected WorkflowController workflowController;
|
protected WorkflowController workflowController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a analytic value as a String for a given key.
|
* Returns a analytic value as a String for a given key.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getAsString(String key) {
|
public String getAsString(String key) {
|
||||||
ItemCollection analyticData = computeValue(key);
|
ItemCollection analyticData = computeValue(key);
|
||||||
return analyticData.getItemValueString("value");
|
return analyticData.getItemValueString("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a analytic value as a Json String for a given key.
|
* Returns a analytic value as a Json String for a given key.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getAsJson(String key) {
|
public String getAsJson(String key) {
|
||||||
ItemCollection analyticData = computeValue(key);
|
ItemCollection analyticData = computeValue(key);
|
||||||
String jsonval = analyticData.getItemValueString("value");
|
String jsonval = analyticData.getItemValueString("value");
|
||||||
if (jsonval == null || jsonval.isEmpty()) {
|
if (jsonval == null || jsonval.isEmpty()) {
|
||||||
return "null";
|
return "null";
|
||||||
} else {
|
} else {
|
||||||
return jsonval;
|
return jsonval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a analytic value as a Double for a given key.
|
* Returns a analytic value as a Double for a given key.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double getAsDouble(String key) {
|
public double getAsDouble(String key) {
|
||||||
ItemCollection analyticData = computeValue(key);
|
ItemCollection analyticData = computeValue(key);
|
||||||
return analyticData.getItemValueDouble("value");
|
return analyticData.getItemValueDouble("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the analytic label for a given key
|
* Returns the analytic label for a given key
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getLabel(String key) {
|
public String getLabel(String key) {
|
||||||
ItemCollection analyticData = computeValue(key);
|
ItemCollection analyticData = computeValue(key);
|
||||||
return analyticData.getItemValueString("label");
|
return analyticData.getItemValueString("label");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the analytic optional link for a given key
|
* Returns the analytic optional link for a given key
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getLink(String key) {
|
public String getLink(String key) {
|
||||||
ItemCollection analyticData = computeValue(key);
|
ItemCollection analyticData = computeValue(key);
|
||||||
return analyticData.getItemValueString("link");
|
return analyticData.getItemValueString("link");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the analytic description for a given key
|
* Returns the analytic description for a given key
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getDescription(String key) {
|
public String getDescription(String key) {
|
||||||
ItemCollection analyticData = computeValue(key);
|
ItemCollection analyticData = computeValue(key);
|
||||||
return analyticData.getItemValueString("description");
|
return analyticData.getItemValueString("description");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes an analytic value. The method cache the value in the
|
* Computes an analytic value. The method cache the value in the item key.
|
||||||
* item key.
|
*
|
||||||
*
|
* An observer controller is responsible to cache or reset the cached values if
|
||||||
* An observer controller is responsible to cache or reset the cached values if
|
* needed.
|
||||||
* needed.
|
*
|
||||||
*
|
* @param key
|
||||||
* @param key
|
* @return
|
||||||
* @return
|
*/
|
||||||
*/
|
protected ItemCollection computeValue(String key) {
|
||||||
protected ItemCollection computeValue(String key) {
|
if (workflowController.getWorkitem() != null) {
|
||||||
if (workflowController.getWorkitem() != null) {
|
logger.fine("fire analytic event for key '" + key + "'");
|
||||||
logger.fine("fire analytic event for key '" + key + "'");
|
// Fire the Analytics Event for this key
|
||||||
// Fire the Analytics Event for this key
|
AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
|
||||||
AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
|
if (analyticEvents != null) {
|
||||||
if (analyticEvents != null) {
|
analyticEvents.fire(event);
|
||||||
analyticEvents.fire(event);
|
if (event.getValue() != null) {
|
||||||
if (event.getValue() != null) {
|
ItemCollection details = new ItemCollection();
|
||||||
ItemCollection details = new ItemCollection();
|
details.setItemValue("value", event.getValue());
|
||||||
details.setItemValue("value", event.getValue());
|
details.setItemValue("label", event.getLabel());
|
||||||
details.setItemValue("label", event.getLabel());
|
details.setItemValue("description", event.getDescription());
|
||||||
details.setItemValue("description", event.getDescription());
|
details.setItemValue("link", event.getLink());
|
||||||
details.setItemValue("link", event.getLink());
|
// cache result
|
||||||
// cache result
|
implodeDetails(key, details);
|
||||||
implodeDetails(key, details);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// analytic value is now already cached!
|
// analytic value is now already cached!
|
||||||
return explodeDetails(key);
|
return explodeDetails(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the List of ItemCollections back into a List of Map elements
|
* Convert the List of ItemCollections back into a List of Map elements
|
||||||
*
|
*
|
||||||
* @param workitem
|
* @param workitem
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes" })
|
@SuppressWarnings({ "rawtypes" })
|
||||||
private void implodeDetails(String key, ItemCollection details) {
|
private void implodeDetails(String key, ItemCollection details) {
|
||||||
// convert the child ItemCollection elements into a List of Map
|
// convert the child ItemCollection elements into a List of Map
|
||||||
List<Map> detailsList = new ArrayList<Map>();
|
List<Map> detailsList = new ArrayList<Map>();
|
||||||
detailsList.add(details.getAllItems());
|
detailsList.add(details.getAllItems());
|
||||||
workflowController.getWorkitem().replaceItemValue(key, detailsList);
|
workflowController.getWorkitem().replaceItemValue(key, detailsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* converts the Map List of a workitem into a List of ItemCollectons
|
* converts the Map List of a workitem into a List of ItemCollectons
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private ItemCollection explodeDetails(String key) {
|
private ItemCollection explodeDetails(String key) {
|
||||||
// convert current list of childItems into ItemCollection elements
|
// convert current list of childItems into ItemCollection elements
|
||||||
List<Object> mapOrderItems = workflowController.getWorkitem().getItemValue(key);
|
List<Object> mapOrderItems = workflowController.getWorkitem().getItemValue(key);
|
||||||
if (mapOrderItems != null && mapOrderItems.size() > 0) {
|
if (mapOrderItems != null && mapOrderItems.size() > 0) {
|
||||||
ItemCollection itemCol = new ItemCollection((Map) mapOrderItems.get(0));
|
ItemCollection itemCol = new ItemCollection((Map) mapOrderItems.get(0));
|
||||||
return itemCol;
|
return itemCol;
|
||||||
}
|
}
|
||||||
// return empty collection
|
// return empty collection
|
||||||
ItemCollection dummy = new ItemCollection();
|
ItemCollection dummy = new ItemCollection();
|
||||||
dummy.setItemValue("value", "");
|
dummy.setItemValue("value", "");
|
||||||
dummy.setItemValue("label", "");
|
dummy.setItemValue("label", "");
|
||||||
dummy.setItemValue("description", "No data available");
|
dummy.setItemValue("description", "No data available");
|
||||||
|
|
||||||
return dummy;
|
return dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@
|
||||||
<ui:define name="scripts">
|
<ui:define name="scripts">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
/*<![CDATA[*/
|
/*<![CDATA[*/
|
||||||
function handleSubmit(event) {
|
function handleSubmit(event) {
|
||||||
// remove ajax kringel
|
// remove ajax kringel
|
||||||
setTimeout(function() {
|
setTimeout(function () {
|
||||||
document.body.classList.remove('loading');
|
document.body.classList.remove('loading');
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
/*]]>*/
|
/*]]>*/
|
||||||
</script>
|
</script>
|
||||||
</ui:define>
|
</ui:define>
|
||||||
|
|
@ -32,7 +32,8 @@
|
||||||
<h:panelGroup layout="block" styleClass="imixs-body" id="analyse_panel">
|
<h:panelGroup layout="block" styleClass="imixs-body" id="analyse_panel">
|
||||||
<div class="imixs-form-panel">
|
<div class="imixs-form-panel">
|
||||||
<div class="ui-state-highlight ui-corner-all" style="margin-bottom: 10px; padding: .5em;">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="imixs-form-section-2">
|
<div class="imixs-form-section-2">
|
||||||
|
|
@ -64,13 +65,15 @@
|
||||||
<dt>
|
<dt>
|
||||||
Abteilung:
|
Abteilung:
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<h:selectOneMenu noSelectionOption="true"
|
<h:selectOneMenu noSelectionOption="true"
|
||||||
value="#{excelExportController.filter.item['space.ref']}">
|
value="#{excelExportController.filter.item['space.ref']}">
|
||||||
<f:selectItem itemLabel=" - " itemValue="-" ></f:selectItem>
|
<f:selectItem itemLabel=" - " itemValue="-"></f:selectItem>
|
||||||
<c:forEach items="#{spaceRefFormController.getSpaces(workflowController.workitem, options)}"
|
<c:forEach
|
||||||
|
items="#{spaceRefFormController.getSpaces(workflowController.workitem, options)}"
|
||||||
var="space">
|
var="space">
|
||||||
<f:selectItem itemLabel="#{space.item['name']}" itemValue="#{space.item['$UniqueID']}">
|
<f:selectItem itemLabel="#{space.item['name']}"
|
||||||
|
itemValue="#{space.item['$UniqueID']}">
|
||||||
</f:selectItem>
|
</f:selectItem>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</h:selectOneMenu>
|
</h:selectOneMenu>
|
||||||
|
|
@ -82,27 +85,26 @@
|
||||||
Debitor:
|
Debitor:
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<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="workitem" value="#{workflowController.workitem}" />
|
||||||
<ui:param name="item" value="#{excelExportController.item}" />
|
<ui:param name="item" value="#{excelExportController.item}" />
|
||||||
</ui:include>
|
</ui:include>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
Positionsnummer:
|
Positionsnummer:
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<h:inputText
|
<h:inputText value="#{excelExportController.filter.item['invoice.text']}">
|
||||||
value="#{excelExportController.filter.item['invoice.text']}">
|
|
||||||
</h:inputText>
|
</h:inputText>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h:commandButton actionListener="#{excelExportController.export()}"
|
<h:commandButton actionListener="#{excelExportController.export()}"
|
||||||
value="Excel Export starten">
|
value="Excel Export starten">
|
||||||
</h:commandButton>
|
</h:commandButton>
|
||||||
<h:commandButton value="#{message.close}" action="notes" />
|
<h:commandButton value="#{message.close}" action="notes" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@
|
||||||
/*]]>*/
|
/*]]>*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h:form id="import_form_id">
|
<h:form id="import_form_id" autocomplete="off">
|
||||||
|
|
||||||
<div class="imixs-form">
|
<div class="imixs-form">
|
||||||
<div class="imixs-header">
|
<div class="imixs-header">
|
||||||
<h1>ZOHO - API </h1>
|
<h1>ZOHO - API </h1>
|
||||||
<!-- ########## Error ########## -->
|
<!-- ########## Error ########## -->
|
||||||
<ui:include src="/error_message.xhtml" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="imixs-body">
|
<div class="imixs-body">
|
||||||
|
|
@ -41,8 +41,27 @@
|
||||||
|
|
||||||
<!-- API Tokens -->
|
<!-- API Tokens -->
|
||||||
<div class="imixs-form-section-2">
|
<div class="imixs-form-section-2">
|
||||||
|
|
||||||
<dl>
|
<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>
|
<dd>
|
||||||
<h:inputText required="false"
|
<h:inputText required="false"
|
||||||
value="#{zohoController.workitem.item['zoho.clientid']}">
|
value="#{zohoController.workitem.item['zoho.clientid']}">
|
||||||
|
|
@ -51,27 +70,20 @@
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Client Secret</dt>
|
<dt>Client Secret <span class="imixs-required">*</span></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<h:inputSecret required="false" redisplay="true"
|
<h:inputSecret required="false" redisplay="true"
|
||||||
value="#{zohoController.workitem.item['zoho.clientsecret']}">
|
value="#{zohoController.workitem.item['zoho.clientsecret']}">
|
||||||
</h:inputSecret>
|
</h:inputSecret>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<dl>
|
|
||||||
<dt>Organization</dt>
|
|
||||||
<dd>
|
|
||||||
<h:inputText required="false"
|
|
||||||
value="#{zohoController.workitem.item['zoho.organization']}">
|
|
||||||
</h:inputText>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Grant Token -->
|
<!-- Grant Token -->
|
||||||
<div class="imixs-form-section-2">
|
<div class="imixs-form-section-2">
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Access Code</dt>
|
<dt>Access Code <span class="imixs-required">*</span> </dt>
|
||||||
<dd>
|
<dd>
|
||||||
<h:inputSecret required="false" redisplay="true"
|
<h:inputSecret required="false" redisplay="true"
|
||||||
value="#{zohoController.workitem.item['zoho.code']}">
|
value="#{zohoController.workitem.item['zoho.code']}">
|
||||||
|
|
|
||||||
|
|
@ -13,46 +13,46 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test generates random test data
|
* This test generates random test data
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestFTP {
|
public class TestFTP {
|
||||||
|
|
||||||
final static String FILE = "/DTVF_SKBeschrift_21010.csv";
|
final static String FILE = "/DTVF_SKBeschrift_21010.csv";
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(TestFTP.class.getName());
|
private final static Logger logger = Logger.getLogger(TestFTP.class.getName());
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Kreditoren import
|
* Test Kreditoren import
|
||||||
*/
|
*/
|
||||||
@Disabled
|
@Disabled
|
||||||
@Test
|
@Test
|
||||||
public void testPutFileToFTP() {
|
public void testPutFileToFTP() {
|
||||||
|
|
||||||
FTPConnector ftpc = new FTPConnector();
|
FTPConnector ftpc = new FTPConnector();
|
||||||
|
|
||||||
ftpc.ftpServer = Optional.ofNullable("u248962.your-storagebox.de");
|
ftpc.ftpServer = Optional.ofNullable("u248962.your-storagebox.de");
|
||||||
ftpc.ftpPort = Optional.ofNullable(21);
|
ftpc.ftpPort = Optional.ofNullable(21);
|
||||||
ftpc.ftpUser = Optional.ofNullable("u248962-sub2");
|
ftpc.ftpUser = Optional.ofNullable("u248962-sub2");
|
||||||
ftpc.ftpPassword = Optional.ofNullable("aXa61n9Un3jDNQlL");
|
ftpc.ftpPassword = Optional.ofNullable("aXa61n9Un3jDNQlL");
|
||||||
ftpc.ftpPath = Optional.ofNullable("/");
|
ftpc.ftpPath = Optional.ofNullable("/");
|
||||||
|
|
||||||
FileData fileData = new FileData("test.txt", "some data...".getBytes(), "text", null);
|
FileData fileData = new FileData("test.txt", "some data...".getBytes(), "text", null);
|
||||||
try {
|
try {
|
||||||
ftpc.put(fileData);
|
ftpc.put(fileData);
|
||||||
logger.info("test finished...");
|
logger.info("test finished...");
|
||||||
} catch (PluginException e) {
|
} catch (PluginException e) {
|
||||||
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test generates random test data
|
* This test generates random test data
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestFormat {
|
public class TestFormat {
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ public class TestFormat {
|
||||||
* ;"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";
|
* ;"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";
|
||||||
* "";"";"";"SO";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";0;"01012023"
|
* "";"";"";"SO";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";0;"01012023"
|
||||||
* ;""
|
* ;""
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDatum() {
|
public void testDatum() {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ import jakarta.mail.Store;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test class test the Imixs IMAPAuthenticator classes
|
* This test class test the Imixs IMAPAuthenticator classes
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestIMAPAuhtenticators {
|
public class TestIMAPAuhtenticators {
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ public class TestIMAPAuhtenticators {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test IMAP connect via OAuth for email address imixs@alexander-logistics.com
|
* Test IMAP connect via OAuth for email address imixs@alexander-logistics.com
|
||||||
*
|
*
|
||||||
* https://techcommunity.microsoft.com/t5/exchange/javamail-connecting-to-office-365-xoauth2-for-imap/m-p/1505026
|
* https://techcommunity.microsoft.com/t5/exchange/javamail-connecting-to-office-365-xoauth2-for-imap/m-p/1505026
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -76,7 +76,7 @@ public class TestIMAPAuhtenticators {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test IMAP connect via OAuth for email address imixs@alexander-logistics.com
|
* Test IMAP connect via OAuth for email address imixs@alexander-logistics.com
|
||||||
*
|
*
|
||||||
* https://techcommunity.microsoft.com/t5/exchange/javamail-connecting-to-office-365-xoauth2-for-imap/m-p/1505026
|
* https://techcommunity.microsoft.com/t5/exchange/javamail-connecting-to-office-365-xoauth2-for-imap/m-p/1505026
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -118,7 +118,7 @@ public class TestIMAPAuhtenticators {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test IMAP connect via OAuth for email address imixs@alexander-logistics.com
|
* Test IMAP connect via OAuth for email address imixs@alexander-logistics.com
|
||||||
*
|
*
|
||||||
* https://techcommunity.microsoft.com/t5/exchange/javamail-connecting-to-office-365-xoauth2-for-imap/m-p/1505026
|
* https://techcommunity.microsoft.com/t5/exchange/javamail-connecting-to-office-365-xoauth2-for-imap/m-p/1505026
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -163,7 +163,7 @@ public class TestIMAPAuhtenticators {
|
||||||
* <p>
|
* <p>
|
||||||
* NOTE: This test should fail in December 2022 as Basic Authentication is no
|
* NOTE: This test should fail in December 2022 as Basic Authentication is no
|
||||||
* longer supported by Microsoft Outlook.
|
* longer supported by Microsoft Outlook.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,11 @@ import jakarta.mail.internet.MimeUtility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test shows how to access outlook via oauth2
|
* This test shows how to access outlook via oauth2
|
||||||
*
|
*
|
||||||
* See: https://www.java-forum.org/thema/javamail-mit-oauth2-an-o365.199133/
|
* See: https://www.java-forum.org/thema/javamail-mit-oauth2-an-o365.199133/
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestIMAPOutlookOAuth {
|
public class TestIMAPOutlookOAuth {
|
||||||
|
|
||||||
|
|
@ -58,9 +58,9 @@ public class TestIMAPOutlookOAuth {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Neue Daten
|
* Neue Daten
|
||||||
*
|
*
|
||||||
* Wert: zDL8Q~iEy8AX~dEmIOHrVv3aBTCZLrHIFmShibZ_
|
* Wert: zDL8Q~iEy8AX~dEmIOHrVv3aBTCZLrHIFmShibZ_ Geheime ID:
|
||||||
* Geheime ID: bcaa558a-3300-4498-94e1-2267f418afd5
|
* bcaa558a-3300-4498-94e1-2267f418afd5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -403,21 +403,21 @@ public class TestIMAPOutlookOAuth {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to receive a Microsoft access Token
|
* Helper method to receive a Microsoft access Token
|
||||||
*
|
*
|
||||||
* https://jwt.ms/
|
* https://jwt.ms/
|
||||||
*
|
*
|
||||||
* "OAuth2": {
|
* "OAuth2": {
|
||||||
*
|
*
|
||||||
* "Authority":
|
* "Authority":
|
||||||
* https://login.microsoftonline.com/51e2f038-0a96-41be-801d-bb4118aa018e/v2.0,
|
* https://login.microsoftonline.com/51e2f038-0a96-41be-801d-bb4118aa018e/v2.0,
|
||||||
*
|
*
|
||||||
* "ClientId": "39e9eec5-6939-47dc-9729-3438a9898e63",
|
* "ClientId": "39e9eec5-6939-47dc-9729-3438a9898e63",
|
||||||
*
|
*
|
||||||
* "ClientSecret": "............."
|
* "ClientSecret": "............."
|
||||||
*
|
*
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws ClientProtocolException
|
* @throws ClientProtocolException
|
||||||
|
|
@ -455,7 +455,7 @@ public class TestIMAPOutlookOAuth {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to read bytes from strem
|
* Helper method to read bytes from strem
|
||||||
*
|
*
|
||||||
* @param inputStream
|
* @param inputStream
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ import com.sun.mail.imap.IMAPFolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test shows how to access outlook via oauth2
|
* This test shows how to access outlook via oauth2
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
public class TestIMAPOutlookOAuthDebug {
|
public class TestIMAPOutlookOAuthDebug {
|
||||||
|
|
@ -223,7 +223,7 @@ public class TestIMAPOutlookOAuthDebug {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to read bytes from stream
|
* Helper method to read bytes from stream
|
||||||
*
|
*
|
||||||
* @param inputStream
|
* @param inputStream
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test tests the InvoicePlugin isCargosoft method
|
* This test tests the InvoicePlugin isCargosoft method
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestModelMatcher {
|
public class TestModelMatcher {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testen der KW Berechnung
|
* Testen der KW Berechnung
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestOPListen {
|
public class TestOPListen {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,24 +7,24 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test generates random test data
|
* This test generates random test data
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestPostionsnummernRegex {
|
public class TestPostionsnummernRegex {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test positionnummern 'XX-YYY-####-###'
|
* Test positionnummern 'XX-YYY-####-###'
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testPutFileToFTP() {
|
public void testPutFileToFTP() {
|
||||||
|
|
||||||
assertTrue("AA-BBC-1234-991".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
assertTrue("AA-BBC-1234-991".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
||||||
assertFalse("aa-BBC-1234-991".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
assertFalse("aa-BBC-1234-991".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
||||||
assertFalse("CC-BBC-1234-991 ".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
assertFalse("CC-BBC-1234-991 ".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
||||||
|
|
||||||
assertTrue("IM-ZEL-2101-005".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
assertTrue("IM-ZEL-2101-005".matches(InvoicePlugin.INVOICE_POSITIONS_PATTERN_DEFAULT));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test generates random test data
|
* This test generates random test data
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestRunden {
|
public class TestRunden {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ public class DueDateBugfix {
|
||||||
* Diese Test Method wandelt die Datei OPD_migration_230126.csv in eine EXTV
|
* Diese Test Method wandelt die Datei OPD_migration_230126.csv in eine EXTV
|
||||||
* Datev Datei um, welche wir dann für einen einmaligen Import der
|
* Datev Datei um, welche wir dann für einen einmaligen Import der
|
||||||
* Rechnugnsdaten verwenden können.
|
* Rechnugnsdaten verwenden können.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
|
|
@ -64,38 +64,24 @@ public class DueDateBugfix {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Erledigte
|
* Erledigte
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* EXTF_202301_202302030602_1295
|
* EXTF_202301_202302030602_1295 EXTF_202301_202302060601_1296
|
||||||
* EXTF_202301_202302060601_1296
|
* EXTF_202301_202302070603_1297 EXTF_202301_202302080603_1298
|
||||||
* EXTF_202301_202302070603_1297
|
* EXTF_202301_202302090604_1299 EXTF_202301_202302100603_1300
|
||||||
* EXTF_202301_202302080603_1298
|
* EXTF_202301_202302130601_1301 EXTF_202301_202302140604_1302
|
||||||
* EXTF_202301_202302090604_1299
|
* EXTF_202301_202302141840_1303 EXTF_202301_202302160944_1304
|
||||||
* EXTF_202301_202302100603_1300
|
* EXTF_202302_202302020601_1294 EXTF_202302_202302030602_1295
|
||||||
* EXTF_202301_202302130601_1301
|
* EXTF_202302_202302060601_1296 EXTF_202302_202302070603_1297
|
||||||
* EXTF_202301_202302140604_1302
|
* EXTF_202302_202302080603_1298 EXTF_202302_202302090604_1299
|
||||||
* EXTF_202301_202302141840_1303
|
* EXTF_202302_202302100604_1300 EXTF_202302_202302130601_1301
|
||||||
* EXTF_202301_202302160944_1304
|
* EXTF_202302_202302140604_1302 EXTF_202302_202302141840_1303
|
||||||
* EXTF_202302_202302020601_1294
|
* EXTF_202302_202302160944_1304 EXTF_202303_202302070603_1297
|
||||||
* EXTF_202302_202302030602_1295
|
* EXTF_202303_202302080603_1298 EXTF_202303_202302090604_1299
|
||||||
* EXTF_202302_202302060601_1296
|
* EXTF_202303_202302100603_1300 EXTF_202303_202302130601_1301
|
||||||
* EXTF_202302_202302070603_1297
|
* EXTF_202303_202302140604_1302 EXTF_202303_202302141840_1303
|
||||||
* 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
|
* EXTF_202303_202302160944_1304
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,10 @@ public class MigrationMahnerAusziffern {
|
||||||
* Diese Test Method wandelt die Datei OPD_migration_230126.csv in eine EXTV
|
* Diese Test Method wandelt die Datei OPD_migration_230126.csv in eine EXTV
|
||||||
* Datev Datei um, welche wir dann für einen einmaligen Import der
|
* Datev Datei um, welche wir dann für einen einmaligen Import der
|
||||||
* Rechnugnsdaten verwenden können.
|
* Rechnugnsdaten verwenden können.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws RestAPIException
|
* @throws RestAPIException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
|
|
@ -131,7 +131,7 @@ public class MigrationMahnerAusziffern {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft eine einzelen Datenzeile
|
* Prüft eine einzelen Datenzeile
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* @param data
|
* @param data
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
|
@ -231,9 +231,9 @@ public class MigrationMahnerAusziffern {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Methode schließt die Rechnungen mit den übergebenen Rechnungsnummer ab
|
* Diese Methode schließt die Rechnungen mit den übergebenen Rechnungsnummer ab
|
||||||
*
|
*
|
||||||
* Beispiel: Bitte Ausziffern : 17755 = "190818" -> "190313"
|
* Beispiel: Bitte Ausziffern : 17755 = "190818" -> "190313"
|
||||||
*
|
*
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
* @throws RestAPIException
|
* @throws RestAPIException
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
|
|
@ -265,7 +265,7 @@ public class MigrationMahnerAusziffern {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Teste ob es diese Rechnung im Office gibt.
|
* Teste ob es diese Rechnung im Office gibt.
|
||||||
*
|
*
|
||||||
* @param rech1
|
* @param rech1
|
||||||
* @throws RestAPIException
|
* @throws RestAPIException
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
|
|
@ -287,7 +287,7 @@ public class MigrationMahnerAusziffern {
|
||||||
/**
|
/**
|
||||||
* Hilfsmethdoe die prüft ob es zu diesr Rechnung shcon eine passende
|
* Hilfsmethdoe die prüft ob es zu diesr Rechnung shcon eine passende
|
||||||
* Gegenrechnung gibt.
|
* Gegenrechnung gibt.
|
||||||
*
|
*
|
||||||
* @param rech
|
* @param rech
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ public class MigrationMahnerDatev {
|
||||||
* Diese Test Method wandelt die Datei OPD_migration_230126.csv in eine EXTV
|
* Diese Test Method wandelt die Datei OPD_migration_230126.csv in eine EXTV
|
||||||
* Datev Datei um, welche wir dann für einen einmaligen Import der
|
* Datev Datei um, welche wir dann für einen einmaligen Import der
|
||||||
* Rechnugnsdaten verwenden können.
|
* Rechnugnsdaten verwenden können.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
|
|
@ -139,7 +139,7 @@ public class MigrationMahnerDatev {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode die einen DATEV Header schreibt
|
* Hilfsmethode die einen DATEV Header schreibt
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
|
|
@ -157,7 +157,7 @@ public class MigrationMahnerDatev {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schreibt eine einzelen Datenzeile
|
* Schreibt eine einzelen Datenzeile
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* @param data
|
* @param data
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test;
|
||||||
/**
|
/**
|
||||||
* Dieser Agent ordnet nachträglich Ausgangsrechnungen aus der Migraiton einem
|
* Dieser Agent ordnet nachträglich Ausgangsrechnungen aus der Migraiton einem
|
||||||
* Space zu.
|
* Space zu.
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -53,11 +53,11 @@ public class MigrationSpaceZuordnung {
|
||||||
/**
|
/**
|
||||||
* Diese methode liest offene Ausgangsrechnungen aus udn prüft of space.ref
|
* Diese methode liest offene Ausgangsrechnungen aus udn prüft of space.ref
|
||||||
* bereits getzt ist.
|
* bereits getzt ist.
|
||||||
*
|
*
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws RestAPIException
|
* @throws RestAPIException
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
|
|
@ -149,7 +149,7 @@ public class MigrationSpaceZuordnung {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method that loads all expressions from the spaces
|
* Helper method that loads all expressions from the spaces
|
||||||
*
|
*
|
||||||
* @return List of list of expressions
|
* @return List of list of expressions
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
* @throws RestAPIException
|
* @throws RestAPIException
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ import jakarta.ws.rs.core.Cookie;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test to request data via a JSESSIONID only....
|
* Test to request data via a JSESSIONID only.... This technique is used by the
|
||||||
* This technique is used by the DataRestService
|
* DataRestService
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Ignore
|
||||||
public class TestDataClient {
|
public class TestDataClient {
|
||||||
|
|
@ -36,11 +36,8 @@ public class TestDataClient {
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() throws PluginException {
|
public void setup() throws PluginException {
|
||||||
// Create a Cookie object with a name and a value
|
// Create a Cookie object with a name and a value
|
||||||
Cookie cookie = new Cookie.Builder("JSESSIONID")
|
Cookie cookie = new Cookie.Builder("JSESSIONID").value(sessionID).path("/")
|
||||||
.value(sessionID)
|
.domain("alexander-logistics.office-workflow.de").build();
|
||||||
.path("/")
|
|
||||||
.domain("alexander-logistics.office-workflow.de")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
client = new DocumentClient(restAPI.trim());
|
client = new DocumentClient(restAPI.trim());
|
||||||
CookieAuthenticator aut = new CookieAuthenticator(cookie);
|
CookieAuthenticator aut = new CookieAuthenticator(cookie);
|
||||||
|
|
@ -51,7 +48,7 @@ public class TestDataClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test to read data....
|
* Test to read data....
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
|
|
|
||||||
|
|
@ -12,71 +12,71 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese Klasse testet die SEPA XSLT Transformation
|
* Diese Klasse testet die SEPA XSLT Transformation
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
public class TestSEPATransform {
|
public class TestSEPATransform {
|
||||||
|
|
||||||
final static String ENCODING = "UTF-8";
|
final static String ENCODING = "UTF-8";
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(TestSEPATransform.class.getName());
|
private static Logger logger = Logger.getLogger(TestSEPATransform.class.getName());
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() throws PluginException, ModelException {
|
public void setup() throws PluginException, ModelException {
|
||||||
logger.info("setup test environment ...");
|
logger.info("setup test environment ...");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XSL Transformation for SEPA Standard file
|
* XSL Transformation for SEPA Standard file
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDefault() throws IOException {
|
public void testDefault() throws IOException {
|
||||||
String MODEL_PATH_XML = "sepa/beispiel-daten.xml";
|
String MODEL_PATH_XML = "sepa/beispiel-daten.xml";
|
||||||
String MODEL_PATH_XSL = "sepa/sepa-2.0.5.xsl";
|
String MODEL_PATH_XSL = "sepa/sepa-2.0.5.xsl";
|
||||||
try {
|
try {
|
||||||
XSLTester.transform(MODEL_PATH_XML, MODEL_PATH_XSL, "../reports/sepa/result_sepa01.xml");
|
XSLTester.transform(MODEL_PATH_XML, MODEL_PATH_XSL, "../reports/sepa/result_sepa01.xml");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XSL Transformation for SEPA file for Bank Polski
|
* XSL Transformation for SEPA file for Bank Polski
|
||||||
*
|
*
|
||||||
* We also test the two-digits case. 10,5 need to become 10,50
|
* We also test the two-digits case. 10,5 need to become 10,50
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBankPolski() throws IOException {
|
public void testBankPolski() throws IOException {
|
||||||
String MODEL_PATH_XML = "sepa/beispiel-daten.xml";
|
String MODEL_PATH_XML = "sepa/beispiel-daten.xml";
|
||||||
String MODEL_PATH_XSL = "sepa/sepa-2.0.11-pl.xsl";
|
String MODEL_PATH_XSL = "sepa/sepa-2.0.11-pl.xsl";
|
||||||
try {
|
try {
|
||||||
XSLTester.transform(MODEL_PATH_XML, MODEL_PATH_XSL, "../reports/sepa/result_sepa-pl.xml");
|
XSLTester.transform(MODEL_PATH_XML, MODEL_PATH_XSL, "../reports/sepa/result_sepa-pl.xml");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XSL Transformation for SEPA file for Bank Polski
|
* XSL Transformation for SEPA file for Bank Polski
|
||||||
*
|
*
|
||||||
* Neue Bank in Polen - bankmillennium
|
* Neue Bank in Polen - bankmillennium
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBankPolskibankmillennium() throws IOException {
|
public void testBankPolskibankmillennium() throws IOException {
|
||||||
String MODEL_PATH_XML = "sepa/beispiel-daten.xml";
|
String MODEL_PATH_XML = "sepa/beispiel-daten.xml";
|
||||||
String MODEL_PATH_XSL = "sepa/sepa-2.0.11-pl_bankmillennium.xsl";
|
String MODEL_PATH_XSL = "sepa/sepa-2.0.11-pl_bankmillennium.xsl";
|
||||||
try {
|
try {
|
||||||
XSLTester.transform(MODEL_PATH_XML, MODEL_PATH_XSL, "../reports/sepa/result_sepa-pl_bankmillennium.xml");
|
XSLTester.transform(MODEL_PATH_XML, MODEL_PATH_XSL, "../reports/sepa/result_sepa-pl_bankmillennium.xml");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ import org.imixs.workflow.xml.XSLHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The XSLTester is used in junit tests to transform XSL/XML files
|
* The XSLTester is used in junit tests to transform XSL/XML files
|
||||||
*
|
*
|
||||||
* Do not forget to change your pom.xml and add the following to your build
|
* Do not forget to change your pom.xml and add the following to your build
|
||||||
* section
|
* section
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@code
|
* {@code
|
||||||
* <testResources>
|
* <testResources>
|
||||||
* <testResource>
|
* <testResource>
|
||||||
* <directory>${basedir}/../reports</directory>
|
* <directory>${basedir}/../reports</directory>
|
||||||
|
|
@ -29,64 +29,64 @@ import org.imixs.workflow.xml.XSLHandler;
|
||||||
* </testResources>
|
* </testResources>
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
public class XSLTester {
|
public class XSLTester {
|
||||||
|
|
||||||
final static String ENCODING = "UTF-8";
|
final static String ENCODING = "UTF-8";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XSL Transformation
|
* XSL Transformation
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws TransformerException
|
* @throws TransformerException
|
||||||
*/
|
*/
|
||||||
public static void transform(String xmlSourcePath, String xslSourcePath, String outputPath)
|
public static void transform(String xmlSourcePath, String xslSourcePath, String outputPath)
|
||||||
throws IOException, TransformerException {
|
throws IOException, TransformerException {
|
||||||
OutputStream outputStream = new FileOutputStream(outputPath);
|
OutputStream outputStream = new FileOutputStream(outputPath);
|
||||||
// Use the class loader to load the XML file as a resource
|
// Use the class loader to load the XML file as a resource
|
||||||
ClassLoader classLoader = XSLTester.class.getClassLoader();
|
ClassLoader classLoader = XSLTester.class.getClassLoader();
|
||||||
InputStream xmlInputStream = classLoader.getResourceAsStream(xmlSourcePath);
|
InputStream xmlInputStream = classLoader.getResourceAsStream(xmlSourcePath);
|
||||||
InputStream xslInputStream = classLoader.getResourceAsStream(xslSourcePath);
|
InputStream xslInputStream = classLoader.getResourceAsStream(xslSourcePath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (xmlInputStream == null) {
|
if (xmlInputStream == null) {
|
||||||
throw new RuntimeException("XML file not found: " + xmlSourcePath);
|
throw new RuntimeException("XML file not found: " + xmlSourcePath);
|
||||||
}
|
}
|
||||||
if (xslInputStream == null) {
|
if (xslInputStream == null) {
|
||||||
throw new RuntimeException("XSL file not found: " + xslSourcePath);
|
throw new RuntimeException("XSL file not found: " + xslSourcePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
String xmlSource = readXml(xmlInputStream);
|
String xmlSource = readXml(xmlInputStream);
|
||||||
String xslSource = readXml(xslInputStream);
|
String xslSource = readXml(xslInputStream);
|
||||||
XSLHandler.transform(xmlSource, xslSource, ENCODING, outputStream);
|
XSLHandler.transform(xmlSource, xslSource, ENCODING, outputStream);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (xmlInputStream != null)
|
if (xmlInputStream != null)
|
||||||
xmlInputStream.close();
|
xmlInputStream.close();
|
||||||
if (xslInputStream != null)
|
if (xslInputStream != null)
|
||||||
xslInputStream.close();
|
xslInputStream.close();
|
||||||
if (outputStream != null)
|
if (outputStream != null)
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read and return the XML content as a String
|
* read and return the XML content as a String
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static String readXml(InputStream inputStream) {
|
private static String readXml(InputStream inputStream) {
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||||
StringBuilder xmlContent = new StringBuilder();
|
StringBuilder xmlContent = new StringBuilder();
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
xmlContent.append(line).append("\n");
|
xmlContent.append(line).append("\n");
|
||||||
}
|
}
|
||||||
return xmlContent.toString();
|
return xmlContent.toString();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Error reading XML file", e);
|
throw new RuntimeException("Error reading XML file", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,86 +34,86 @@ import com.alexanderlogistics.mahnlauf.MahnlaufService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testet den Import Vorgang anhand einer Cargosoft XML Datei
|
* Testet den Import Vorgang anhand einer Cargosoft XML Datei
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@MockitoSettings(strictness = Strictness.WARN)
|
@MockitoSettings(strictness = Strictness.WARN)
|
||||||
public class EAkteImportTester {
|
public class EAkteImportTester {
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private CargosoftXMLEAkteImportService service;
|
private CargosoftXMLEAkteImportService service;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private DocumentService documentService;
|
private DocumentService documentService;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private BusinessPartnerService businessPartnerService;
|
private BusinessPartnerService businessPartnerService;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private MahnlaufService mahnlaufService;
|
private MahnlaufService mahnlaufService;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
// Mock protected Methode 'alreadyImported' -> always false
|
// Mock protected Methode 'alreadyImported' -> always false
|
||||||
Mockito.when(service.alreadyImported(Mockito.anyString())).thenReturn(false);
|
Mockito.when(service.alreadyImported(Mockito.anyString())).thenReturn(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ein Einfacher test
|
* Ein Einfacher test
|
||||||
*
|
*
|
||||||
* @throws TransformerException
|
* @throws TransformerException
|
||||||
* @throws XPathExpressionException
|
* @throws XPathExpressionException
|
||||||
* @throws ModelException
|
* @throws ModelException
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws ProcessingErrorException
|
* @throws ProcessingErrorException
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testEAkteBasic() throws Exception {
|
public void testEAkteBasic() throws Exception {
|
||||||
|
|
||||||
ItemCollection source = new ItemCollection();
|
ItemCollection source = new ItemCollection();
|
||||||
String fileName = "Abgabenbescheid-IM-GCA-2408-116N-001-ATC400012650820242452-_20240806164256864_DEBUG.xml";
|
String fileName = "Abgabenbescheid-IM-GCA-2408-116N-001-ATC400012650820242452-_20240806164256864_DEBUG.xml";
|
||||||
byte[] xmlContent = readTestFile("cargosoft/" + fileName);
|
byte[] xmlContent = readTestFile("cargosoft/" + fileName);
|
||||||
assertNotNull(xmlContent);
|
assertNotNull(xmlContent);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ItemCollection result = service.createWorkitem(source, fileName, xmlContent, new HashMap<>());
|
ItemCollection result = service.createWorkitem(source, fileName, xmlContent, new HashMap<>());
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals("001", result.getItemValueString("mandant.id"));
|
assertEquals("001", result.getItemValueString("mandant.id"));
|
||||||
|
|
||||||
// test Rows
|
// test Rows
|
||||||
List<ItemCollection> rows = InvoiceUtil.explodeChildList(result);
|
List<ItemCollection> rows = InvoiceUtil.explodeChildList(result);
|
||||||
assertNotNull(rows);
|
assertNotNull(rows);
|
||||||
assertEquals(2, rows.size());
|
assertEquals(2, rows.size());
|
||||||
ItemCollection row1 = rows.get(0);
|
ItemCollection row1 = rows.get(0);
|
||||||
ItemCollection row2 = rows.get(1);
|
ItemCollection row2 = rows.get(1);
|
||||||
assertEquals("LA-ZEL-2403-004", row1.getItemValueString("filenumber"));
|
assertEquals("LA-ZEL-2403-004", row1.getItemValueString("filenumber"));
|
||||||
assertEquals("LA-ZEL-2403-00", row2.getItemValueString("filenumber"));
|
assertEquals("LA-ZEL-2403-00", row2.getItemValueString("filenumber"));
|
||||||
assertEquals("ZOLL", row1.getItemValueString("activity.type"));
|
assertEquals("ZOLL", row1.getItemValueString("activity.type"));
|
||||||
assertEquals("EUST", row2.getItemValueString("activity.type"));
|
assertEquals("EUST", row2.getItemValueString("activity.type"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode zum einlesen einer xml test datei
|
* Hilfsmethode zum einlesen einer xml test datei
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private byte[] readTestFile(String filename) throws IOException {
|
private byte[] readTestFile(String filename) throws IOException {
|
||||||
// Load the file from the resources folder
|
// Load the file from the resources folder
|
||||||
ClassLoader classLoader = getClass().getClassLoader();
|
ClassLoader classLoader = getClass().getClassLoader();
|
||||||
InputStream inputStream = classLoader.getResourceAsStream(filename);
|
InputStream inputStream = classLoader.getResourceAsStream(filename);
|
||||||
byte[] data = inputStream.readAllBytes();
|
byte[] data = inputStream.readAllBytes();
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,131 +34,131 @@ import com.alexanderlogistics.mahnlauf.MahnlaufService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testet den Import Vorgang anhand einer Cargosoft XML Datei
|
* Testet den Import Vorgang anhand einer Cargosoft XML Datei
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@MockitoSettings(strictness = Strictness.WARN)
|
@MockitoSettings(strictness = Strictness.WARN)
|
||||||
public class InvoiceImportTester {
|
public class InvoiceImportTester {
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private CargosoftXMLInvoiceImportService service;
|
private CargosoftXMLInvoiceImportService service;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private DocumentService documentService;
|
private DocumentService documentService;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private MahnlaufService mahnlaufService;
|
private MahnlaufService mahnlaufService;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private BusinessPartnerService businessPartnerService;
|
private BusinessPartnerService businessPartnerService;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
// Mock protected Methode 'alreadyImported' -> always false
|
// Mock protected Methode 'alreadyImported' -> always false
|
||||||
Mockito.when(service.alreadyImported(Mockito.anyString())).thenReturn(false);
|
Mockito.when(service.alreadyImported(Mockito.anyString())).thenReturn(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ein Einfacher test
|
* Ein Einfacher test
|
||||||
*
|
*
|
||||||
* @throws TransformerException
|
* @throws TransformerException
|
||||||
* @throws XPathExpressionException
|
* @throws XPathExpressionException
|
||||||
* @throws ModelException
|
* @throws ModelException
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
* @throws ProcessingErrorException
|
* @throws ProcessingErrorException
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvoiceBasic() throws Exception {
|
public void testInvoiceBasic() throws Exception {
|
||||||
|
|
||||||
ItemCollection source = new ItemCollection();
|
ItemCollection source = new ItemCollection();
|
||||||
String fileName = "001_R_224380_110136787.xml";
|
String fileName = "001_R_224380_110136787.xml";
|
||||||
byte[] xmlContent = readTestFile("cargosoft/" + fileName);
|
byte[] xmlContent = readTestFile("cargosoft/" + fileName);
|
||||||
assertNotNull(xmlContent);
|
assertNotNull(xmlContent);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ItemCollection result = service.createWorkitem(source, fileName, xmlContent, new HashMap<>());
|
ItemCollection result = service.createWorkitem(source, fileName, xmlContent, new HashMap<>());
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals("001", result.getItemValueString("mandant.id"));
|
assertEquals("001", result.getItemValueString("mandant.id"));
|
||||||
|
|
||||||
// test Rows
|
// test Rows
|
||||||
List<ItemCollection> rows = InvoiceUtil.explodeChildList(result);
|
List<ItemCollection> rows = InvoiceUtil.explodeChildList(result);
|
||||||
assertNotNull(rows);
|
assertNotNull(rows);
|
||||||
assertEquals(2, rows.size());
|
assertEquals(2, rows.size());
|
||||||
ItemCollection row1 = rows.get(0);
|
ItemCollection row1 = rows.get(0);
|
||||||
ItemCollection row2 = rows.get(1);
|
ItemCollection row2 = rows.get(1);
|
||||||
assertEquals("EX-GCA-2408-042", row1.getItemValueString("datev.text"));
|
assertEquals("EX-GCA-2408-042", row1.getItemValueString("datev.text"));
|
||||||
assertEquals("EX-GCA-2408-042", row2.getItemValueString("datev.text"));
|
assertEquals("EX-GCA-2408-042", row2.getItemValueString("datev.text"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ein ATC test
|
* Ein ATC test
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInvoiceATC() throws Exception {
|
public void testInvoiceATC() throws Exception {
|
||||||
|
|
||||||
ItemCollection source = new ItemCollection();
|
ItemCollection source = new ItemCollection();
|
||||||
String fileName = "001_R_224225_115103063.xml";
|
String fileName = "001_R_224225_115103063.xml";
|
||||||
byte[] xmlContent = readTestFile("cargosoft/" + fileName);
|
byte[] xmlContent = readTestFile("cargosoft/" + fileName);
|
||||||
assertNotNull(xmlContent);
|
assertNotNull(xmlContent);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ItemCollection result = service.createWorkitem(source, fileName, xmlContent, new HashMap<>());
|
ItemCollection result = service.createWorkitem(source, fileName, xmlContent, new HashMap<>());
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals("001", result.getItemValueString("mandant.id"));
|
assertEquals("001", result.getItemValueString("mandant.id"));
|
||||||
assertEquals("ATC400012650820242452", result.getItemValueString("invoice.atc.number"));
|
assertEquals("ATC400012650820242452", result.getItemValueString("invoice.atc.number"));
|
||||||
assertEquals(3752.95, result.getItemValueDouble("invoice.total"), 0.0);
|
assertEquals(3752.95, result.getItemValueDouble("invoice.total"), 0.0);
|
||||||
|
|
||||||
// test Rows
|
// test Rows
|
||||||
List<ItemCollection> rows = InvoiceUtil.explodeChildList(result);
|
List<ItemCollection> rows = InvoiceUtil.explodeChildList(result);
|
||||||
assertNotNull(rows);
|
assertNotNull(rows);
|
||||||
assertEquals(2, rows.size());
|
assertEquals(2, rows.size());
|
||||||
ItemCollection row1 = rows.get(0);
|
ItemCollection row1 = rows.get(0);
|
||||||
assertEquals("IM-GCA-2408-116", row1.getItemValueString("datev.text"));
|
assertEquals("IM-GCA-2408-116", row1.getItemValueString("datev.text"));
|
||||||
assertEquals("EUST", row1.getItemValueString("category"));
|
assertEquals("EUST", row1.getItemValueString("category"));
|
||||||
assertEquals("EUST", row1.getItemValueString("BillingCode"));
|
assertEquals("EUST", row1.getItemValueString("BillingCode"));
|
||||||
// test BillingText
|
// test BillingText
|
||||||
List<String> billingTextList = row1.getItemValue("BillingText");
|
List<String> billingTextList = row1.getItemValue("BillingText");
|
||||||
assertEquals(2, billingTextList.size());
|
assertEquals(2, billingTextList.size());
|
||||||
// test ATC Number
|
// test ATC Number
|
||||||
assertEquals("ATC400012650820242452", row1.getItemValueString("atc.number"));
|
assertEquals("ATC400012650820242452", row1.getItemValueString("atc.number"));
|
||||||
// Umsatz
|
// Umsatz
|
||||||
assertEquals(3591.34, row1.getItemValueDouble("datev.umsatz"), 0.0);
|
assertEquals(3591.34, row1.getItemValueDouble("datev.umsatz"), 0.0);
|
||||||
|
|
||||||
ItemCollection row2 = rows.get(1);
|
ItemCollection row2 = rows.get(1);
|
||||||
assertEquals("IM-GCA-2408-116", row2.getItemValueString("datev.text"));
|
assertEquals("IM-GCA-2408-116", row2.getItemValueString("datev.text"));
|
||||||
assertEquals("SONST", row2.getItemValueString("category"));
|
assertEquals("SONST", row2.getItemValueString("category"));
|
||||||
// Umsatz
|
// Umsatz
|
||||||
assertEquals(161.61, row2.getItemValueDouble("datev.umsatz"), 0.0);
|
assertEquals(161.61, row2.getItemValueDouble("datev.umsatz"), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hilfsmethode zum einlesen einer xml test datei
|
* Hilfsmethode zum einlesen einer xml test datei
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private byte[] readTestFile(String filename) throws IOException {
|
private byte[] readTestFile(String filename) throws IOException {
|
||||||
// Load the file from the resources folder
|
// Load the file from the resources folder
|
||||||
ClassLoader classLoader = getClass().getClassLoader();
|
ClassLoader classLoader = getClass().getClassLoader();
|
||||||
InputStream inputStream = classLoader.getResourceAsStream(filename);
|
InputStream inputStream = classLoader.getResourceAsStream(filename);
|
||||||
byte[] data = inputStream.readAllBytes();
|
byte[] data = inputStream.readAllBytes();
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,247 +26,225 @@ import jakarta.json.bind.JsonbBuilder;
|
||||||
/**
|
/**
|
||||||
* Diese Klasse generiert einen access und refresh token anhand eines Code
|
* Diese Klasse generiert einen access und refresh token anhand eines Code
|
||||||
* Tokens
|
* Tokens
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
*/
|
*/
|
||||||
@Disabled
|
@Disabled
|
||||||
public class TestUpdateTokens {
|
public class TestUpdateTokens {
|
||||||
|
|
||||||
final static String ENCODING = "UTF-8";
|
final static String ENCODING = "UTF-8";
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(TestUpdateTokens.class.getName());
|
private static Logger logger = Logger.getLogger(TestUpdateTokens.class.getName());
|
||||||
|
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private Jsonb jsonb;
|
private Jsonb jsonb;
|
||||||
|
|
||||||
private String redirectURI = "https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant";
|
private String redirectURI = "https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant";
|
||||||
|
|
||||||
private String clientID = "1000.GR5FTPZYB06HEWSFSSX4DJU3OBD4EJ";
|
private String clientID = "1000.GR5FTPZYB06HEWSFSSX4DJU3OBD4EJ";
|
||||||
private String clientSecret = "3f3e74c5212bbc924a7ebf77f887c6296db1106c47";
|
private String clientSecret = "3f3e74c5212bbc924a7ebf77f887c6296db1106c47";
|
||||||
|
|
||||||
private String code = null;
|
private String code = null;
|
||||||
private String accessToken = null;
|
private String accessToken = null;
|
||||||
private String refreshToken = null;
|
private String refreshToken = null;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() throws PluginException, ModelException {
|
public void setup() throws PluginException, ModelException {
|
||||||
logger.info("setup test environment ...");
|
logger.info("setup test environment ...");
|
||||||
this.httpClient = HttpClient.newBuilder()
|
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||||
.connectTimeout(Duration.ofSeconds(10))
|
this.jsonb = JsonbBuilder.create();
|
||||||
.build();
|
}
|
||||||
this.jsonb = JsonbBuilder.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testet den Vorgang einen Access und Refresh Token zu generieren
|
* Testet den Vorgang einen Access und Refresh Token zu generieren
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateTokens() throws IOException {
|
public void testUpdateTokens() throws IOException {
|
||||||
|
|
||||||
logger.info("├── update Zoho tokens");
|
logger.info("├── update Zoho tokens");
|
||||||
refreshToken = null;
|
refreshToken = null;
|
||||||
accessToken = null;
|
accessToken = null;
|
||||||
code = "1000.48bd85a3965cf724f4691757cfd8d93b.8ae5e3ee7d70f90d307da4d289a9b067";
|
code = "1000.48bd85a3965cf724f4691757cfd8d93b.8ae5e3ee7d70f90d307da4d289a9b067";
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
|
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
|
||||||
"?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
||||||
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
"&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
|
||||||
"&redirect_uri=" + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
|
||||||
"&grant_type=authorization_code";
|
|
||||||
|
|
||||||
logger.info("│ ├── Request URI=" + requestUrl);
|
logger.info("│ ├── Request URI=" + requestUrl);
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
|
||||||
.uri(URI.create(requestUrl))
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
||||||
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
.build();
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
|
|
||||||
response = httpClient.send(request,
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
||||||
if (response.statusCode() == 200) {
|
if (response.statusCode() == 200) {
|
||||||
|
|
||||||
// 1. Response-Logging für Debugging
|
// 1. Response-Logging für Debugging
|
||||||
logger.info("│ ├── Response Body=" + response.body());
|
logger.info("│ ├── Response Body=" + response.body());
|
||||||
|
|
||||||
assertNotNull(response.body());
|
assertNotNull(response.body());
|
||||||
assertFalse(response.body().contains("error"));
|
assertFalse(response.body().contains("error"));
|
||||||
|
|
||||||
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
|
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
|
||||||
TokenResponse.class);
|
|
||||||
|
|
||||||
accessToken = tokenResponse.getAccess_token();
|
accessToken = tokenResponse.getAccess_token();
|
||||||
assertNotNull(accessToken);
|
assertNotNull(accessToken);
|
||||||
logger.info("│ ├── accessToken=" + accessToken);
|
logger.info("│ ├── accessToken=" + accessToken);
|
||||||
refreshToken = tokenResponse.getRefresh_token();
|
refreshToken = tokenResponse.getRefresh_token();
|
||||||
logger.info("│ ├── refreshToken=" + refreshToken);
|
logger.info("│ ├── refreshToken=" + refreshToken);
|
||||||
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
|
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Failed to get tokens: " +
|
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
|
||||||
response.statusCode() + " - " + response.body());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testet den Refresh Token
|
* Testet den Refresh Token
|
||||||
*
|
*
|
||||||
* POST:
|
* POST:
|
||||||
* {Accounts_URL}/oauth/v2/token?refresh_token={refresh_token}&client_id={client_id}&client_secret={client_secret}&grant_type=refresh_token
|
* {Accounts_URL}/oauth/v2/token?refresh_token={refresh_token}&client_id={client_id}&client_secret={client_secret}&grant_type=refresh_token
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testRefreshAccessToken() throws IOException {
|
public void testRefreshAccessToken() throws IOException {
|
||||||
|
|
||||||
logger.info("├── refresh Zoho access token");
|
logger.info("├── refresh Zoho access token");
|
||||||
refreshToken = "1000.cf458816e97f848df8134ce1c7e923a1.5b9dbdee317e35d7f0c619e7648d55ff";
|
refreshToken = "1000.cf458816e97f848df8134ce1c7e923a1.5b9dbdee317e35d7f0c619e7648d55ff";
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
|
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?refresh_token="
|
||||||
"?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) + "&client_id="
|
||||||
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
"&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) +
|
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=refresh_token";
|
||||||
"&grant_type=refresh_token";
|
|
||||||
|
|
||||||
logger.info("│ ├── Request URI=" + requestUrl);
|
logger.info("│ ├── Request URI=" + requestUrl);
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
|
||||||
.uri(URI.create(requestUrl))
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
||||||
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
|
.build();
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
|
|
||||||
response = httpClient.send(request,
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
||||||
if (response.statusCode() == 200) {
|
if (response.statusCode() == 200) {
|
||||||
|
|
||||||
// 1. Response-Logging für Debugging
|
// 1. Response-Logging für Debugging
|
||||||
logger.info("│ ├── Response Body=" + response.body());
|
logger.info("│ ├── Response Body=" + response.body());
|
||||||
|
|
||||||
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
|
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
|
||||||
TokenResponse.class);
|
|
||||||
|
|
||||||
String accessToken = tokenResponse.getAccess_token();
|
String accessToken = tokenResponse.getAccess_token();
|
||||||
logger.info("│ ├── accessToken=" + accessToken);
|
logger.info("│ ├── accessToken=" + accessToken);
|
||||||
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
|
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Failed to get tokens: " +
|
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
|
||||||
response.statusCode() + " - " + response.body());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testet den eigentlichen API Zugriff mit Hilfe des zuvor generieren Access
|
* Testet den eigentlichen API Zugriff mit Hilfe des zuvor generieren Access
|
||||||
* Token
|
* Token
|
||||||
*
|
*
|
||||||
* GET: https://{zohoapis_domain}/writer/api/v1/documents
|
* GET: https://{zohoapis_domain}/writer/api/v1/documents
|
||||||
*
|
*
|
||||||
* @see https://www.zoho.com/books/api/v3/introduction/#overview
|
* @see https://www.zoho.com/books/api/v3/introduction/#overview
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetOrganizations() throws IOException {
|
public void testGetOrganizations() throws IOException {
|
||||||
|
|
||||||
logger.info("├── get Zoho organizations");
|
logger.info("├── get Zoho organizations");
|
||||||
accessToken = "1000.21912dc6af0906707f51d336fd98ab61.eb153952d0d86a828fcb7e18426c2c1a";
|
accessToken = "1000.21912dc6af0906707f51d336fd98ab61.eb153952d0d86a828fcb7e18426c2c1a";
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String url = "https://www.zohoapis.eu/books/v3/organizations";
|
String url = "https://www.zohoapis.eu/books/v3/organizations";
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET()
|
||||||
.uri(URI.create(url))
|
.header("Authorization", "Zoho-oauthtoken " + accessToken).build();
|
||||||
.GET()
|
|
||||||
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
request,
|
|
||||||
HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
||||||
|
|
||||||
// 1. Response-Logging für Debugging
|
// 1. Response-Logging für Debugging
|
||||||
logger.info("│ ├── Response Body=" + response.body());
|
logger.info("│ ├── Response Body=" + response.body());
|
||||||
|
|
||||||
if (response.statusCode() >= 300) {
|
if (response.statusCode() >= 300) {
|
||||||
|
|
||||||
throw new RuntimeException("API request failed with status code: " + response.statusCode());
|
throw new RuntimeException("API request failed with status code: " + response.statusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testet den eigentlichen API Zugriff mit Hilfe des zuvor generieren Access
|
* Testet den eigentlichen API Zugriff mit Hilfe des zuvor generieren Access
|
||||||
* Token
|
* Token
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* curl --request GET \
|
* curl --request GET \ --url
|
||||||
* --url 'https://www.zohoapis.com/books/v3/invoices?organization_id=10234695' \
|
* 'https://www.zohoapis.com/books/v3/invoices?organization_id=10234695' \
|
||||||
* --header 'Authorization: Zoho-oauthtoken
|
* --header 'Authorization: Zoho-oauthtoken
|
||||||
* 1000.41d9xxxxxxxxxxxxxxxxxxxxxxxxc2d1.8fccxxxxxxxxxxxxxxxxxxxxxxxx125f'
|
* 1000.41d9xxxxxxxxxxxxxxxxxxxxxxxxc2d1.8fccxxxxxxxxxxxxxxxxxxxxxxxx125f'
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetInvoices() throws IOException {
|
public void testGetInvoices() throws IOException {
|
||||||
|
|
||||||
logger.info("├── get Zoho documents");
|
logger.info("├── get Zoho documents");
|
||||||
accessToken = "1000.21912dc6af0906707f51d336fd98ab61.eb153952d0d86a828fcb7e18426c2c1a";
|
accessToken = "1000.21912dc6af0906707f51d336fd98ab61.eb153952d0d86a828fcb7e18426c2c1a";
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String url = "https://www.zohoapis.eu/books/v3/invoices?organization_id=20105697367";
|
String url = "https://www.zohoapis.eu/books/v3/invoices?organization_id=20105697367";
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET()
|
||||||
.uri(URI.create(url))
|
.header("Authorization", "Zoho-oauthtoken " + accessToken).build();
|
||||||
.GET()
|
|
||||||
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
request,
|
|
||||||
HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
||||||
|
|
||||||
// 1. Response-Logging für Debugging
|
// 1. Response-Logging für Debugging
|
||||||
logger.info("│ ├── Response Body=" + response.body());
|
logger.info("│ ├── Response Body=" + response.body());
|
||||||
|
|
||||||
if (response.statusCode() >= 300) {
|
if (response.statusCode() >= 300) {
|
||||||
|
|
||||||
throw new RuntimeException("API request failed with status code: " + response.statusCode());
|
throw new RuntimeException("API request failed with status code: " + response.statusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
throw new InvalidAccessException("Unable to resolve access tokens: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,97 +1,97 @@
|
||||||
{
|
{
|
||||||
"code": 0,
|
"code" : 0,
|
||||||
"message": "success",
|
"message" : "success",
|
||||||
"invoices": [
|
"invoices" : [
|
||||||
{
|
{
|
||||||
"ach_payment_initiated": false,
|
"ach_payment_initiated" : false,
|
||||||
"invoice_id": "777249000000055583",
|
"invoice_id" : "777249000000055583",
|
||||||
"zcrm_potential_id": "",
|
"zcrm_potential_id" : "",
|
||||||
"customer_id": "777249000000055569",
|
"customer_id" : "777249000000055569",
|
||||||
"zcrm_potential_name": "",
|
"zcrm_potential_name" : "",
|
||||||
"customer_name": "Mr. Foo",
|
"customer_name" : "Mr. Foo",
|
||||||
"company_name": "",
|
"company_name" : "",
|
||||||
"status": "overdue",
|
"status" : "overdue",
|
||||||
"invoice_number": "INV-000001",
|
"invoice_number" : "INV-000001",
|
||||||
"reference_number": "23452345",
|
"reference_number" : "23452345",
|
||||||
"date": "2025-04-21",
|
"date" : "2025-04-21",
|
||||||
"due_date": "2025-04-21",
|
"due_date" : "2025-04-21",
|
||||||
"due_days": "Overdue by 3 days",
|
"due_days" : "Overdue by 3 days",
|
||||||
"email": "ralph.soika@imixs.com",
|
"email" : "ralph.soika@imixs.com",
|
||||||
"project_name": "",
|
"project_name" : "",
|
||||||
"billing_address": {
|
"billing_address" : {
|
||||||
"address": "",
|
"address" : "",
|
||||||
"street2": "",
|
"street2" : "",
|
||||||
"city": "",
|
"city" : "",
|
||||||
"state": "",
|
"state" : "",
|
||||||
"zipcode": "",
|
"zipcode" : "",
|
||||||
"country": "",
|
"country" : "",
|
||||||
"phone": "",
|
"phone" : "",
|
||||||
"fax": "",
|
"fax" : "",
|
||||||
"attention": ""
|
"attention" : ""
|
||||||
},
|
},
|
||||||
"shipping_address": {
|
"shipping_address" : {
|
||||||
"address": "",
|
"address" : "",
|
||||||
"street2": "",
|
"street2" : "",
|
||||||
"city": "",
|
"city" : "",
|
||||||
"state": "",
|
"state" : "",
|
||||||
"zipcode": "",
|
"zipcode" : "",
|
||||||
"country": "",
|
"country" : "",
|
||||||
"phone": "",
|
"phone" : "",
|
||||||
"fax": "",
|
"fax" : "",
|
||||||
"attention": ""
|
"attention" : ""
|
||||||
},
|
},
|
||||||
"country": "",
|
"country" : "",
|
||||||
"phone": "",
|
"phone" : "",
|
||||||
"created_by": "Ralph Soika",
|
"created_by" : "Ralph Soika",
|
||||||
"total": 50.00,
|
"total" : 50.0,
|
||||||
"balance": 50.00,
|
"balance" : 50.0,
|
||||||
"payment_expected_date": "",
|
"payment_expected_date" : "",
|
||||||
"custom_fields": [],
|
"custom_fields" : [ ],
|
||||||
"custom_field_hash": {},
|
"custom_field_hash" : { },
|
||||||
"tags": [],
|
"tags" : [ ],
|
||||||
"salesperson_name": "",
|
"salesperson_name" : "",
|
||||||
"shipping_charge": 0.00,
|
"shipping_charge" : 0.0,
|
||||||
"adjustment": 0.00,
|
"adjustment" : 0.0,
|
||||||
"created_time": "2025-04-21T13:36:26+0200",
|
"created_time" : "2025-04-21T13:36:26+0200",
|
||||||
"last_modified_time": "2025-04-21T13:42:56+0200",
|
"last_modified_time" : "2025-04-21T13:42:56+0200",
|
||||||
"updated_time": "2025-04-21T13:42:56+0200",
|
"updated_time" : "2025-04-21T13:42:56+0200",
|
||||||
"is_viewed_by_client": false,
|
"is_viewed_by_client" : false,
|
||||||
"has_attachment": true,
|
"has_attachment" : true,
|
||||||
"client_viewed_time": "",
|
"client_viewed_time" : "",
|
||||||
"is_viewed_in_mail": false,
|
"is_viewed_in_mail" : false,
|
||||||
"is_emailed": true,
|
"is_emailed" : true,
|
||||||
"mail_first_viewed_time": "",
|
"mail_first_viewed_time" : "",
|
||||||
"mail_last_viewed_time": "",
|
"mail_last_viewed_time" : "",
|
||||||
"is_correction_invoice": false,
|
"is_correction_invoice" : false,
|
||||||
"color_code": "",
|
"color_code" : "",
|
||||||
"current_sub_status_id": "",
|
"current_sub_status_id" : "",
|
||||||
"current_sub_status": "overdue",
|
"current_sub_status" : "overdue",
|
||||||
"currency_id": "777249000000000071",
|
"currency_id" : "777249000000000071",
|
||||||
"schedule_time": "",
|
"schedule_time" : "",
|
||||||
"currency_code": "EUR",
|
"currency_code" : "EUR",
|
||||||
"currency_symbol": "€",
|
"currency_symbol" : "€",
|
||||||
"template_type": "standard",
|
"template_type" : "standard",
|
||||||
"invoice_url": "https://zohosecurepay.eu/books/imixs/secure?CInvoiceID=2-64277fbd3cd8bc86f8e581a3a7e1544618c191c094de1ae938827291b0828c92b5f796a1ec94bfb1fdcce7621ddf18bf61770563d9fd283207b7fa0e24d232a416b0b5e010c61cd7 ",
|
"invoice_url" : "https://zohosecurepay.eu/books/imixs/secure?CInvoiceID=2-64277fbd3cd8bc86f8e581a3a7e1544618c191c094de1ae938827291b0828c92b5f796a1ec94bfb1fdcce7621ddf18bf61770563d9fd283207b7fa0e24d232a416b0b5e010c61cd7 ",
|
||||||
"transaction_type": "renewal",
|
"transaction_type" : "renewal",
|
||||||
"reminders_sent": 0,
|
"reminders_sent" : 0,
|
||||||
"last_reminder_sent_date": "",
|
"last_reminder_sent_date" : "",
|
||||||
"last_payment_date": "",
|
"last_payment_date" : "",
|
||||||
"template_id": "777249000000000103",
|
"template_id" : "777249000000000103",
|
||||||
"documents": "",
|
"documents" : "",
|
||||||
"salesperson_id": "",
|
"salesperson_id" : "",
|
||||||
"write_off_amount": 0.00,
|
"write_off_amount" : 0.0,
|
||||||
"exchange_rate": 1.00,
|
"exchange_rate" : 1.0,
|
||||||
"unprocessed_payment_amount": 0.00
|
"unprocessed_payment_amount" : 0.0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"page_context": {
|
"page_context" : {
|
||||||
"page": 1,
|
"page" : 1,
|
||||||
"per_page": 200,
|
"per_page" : 200,
|
||||||
"has_more_page": false,
|
"has_more_page" : false,
|
||||||
"report_name": "Invoices",
|
"report_name" : "Invoices",
|
||||||
"applied_filter": "Status.All",
|
"applied_filter" : "Status.All",
|
||||||
"custom_fields": [],
|
"custom_fields" : [ ],
|
||||||
"sort_column": "created_time",
|
"sort_column" : "created_time",
|
||||||
"sort_order": "D"
|
"sort_order" : "D"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
39
pom.xml
39
pom.xml
|
|
@ -128,8 +128,45 @@
|
||||||
<encoding>${project.build.sourceEncoding}</encoding>
|
<encoding>${project.build.sourceEncoding}</encoding>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</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>
|
<finalName>office-alexander-logistics</finalName>
|
||||||
</build>
|
</build>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@
|
||||||
<bpmn2:flowNodeRef>event_kT136g</bpmn2:flowNodeRef>
|
<bpmn2:flowNodeRef>event_kT136g</bpmn2:flowNodeRef>
|
||||||
<bpmn2:flowNodeRef>event_jkHxJA</bpmn2:flowNodeRef>
|
<bpmn2:flowNodeRef>event_jkHxJA</bpmn2:flowNodeRef>
|
||||||
<bpmn2:flowNodeRef>event_zzWQSA</bpmn2:flowNodeRef>
|
<bpmn2:flowNodeRef>event_zzWQSA</bpmn2:flowNodeRef>
|
||||||
|
<bpmn2:flowNodeRef>event_k4Ms1Q</bpmn2:flowNodeRef>
|
||||||
</bpmn2:lane>
|
</bpmn2:lane>
|
||||||
</bpmn2:laneSet>
|
</bpmn2:laneSet>
|
||||||
<bpmn2:task id="task_ToMZaQ" imixs:processid="1000" name="Neuanlage">
|
<bpmn2:task id="task_ToMZaQ" imixs:processid="1000" name="Neuanlage">
|
||||||
|
|
@ -155,6 +156,7 @@
|
||||||
<bpmn2:outgoing>sequenceFlow_03b60w</bpmn2:outgoing>
|
<bpmn2:outgoing>sequenceFlow_03b60w</bpmn2:outgoing>
|
||||||
<bpmn2:incoming>sequenceFlow_u8PLGw</bpmn2:incoming>
|
<bpmn2:incoming>sequenceFlow_u8PLGw</bpmn2:incoming>
|
||||||
<bpmn2:incoming>sequenceFlow_ZTiO7w</bpmn2:incoming>
|
<bpmn2:incoming>sequenceFlow_ZTiO7w</bpmn2:incoming>
|
||||||
|
<bpmn2:incoming>sequenceFlow_gIdPow</bpmn2:incoming>
|
||||||
</bpmn2:task>
|
</bpmn2:task>
|
||||||
<bpmn2:task id="task_B8Pi7A" imixs:processid="1800" name="Locked">
|
<bpmn2:task id="task_B8Pi7A" imixs:processid="1800" name="Locked">
|
||||||
<bpmn2:extensionElements>
|
<bpmn2:extensionElements>
|
||||||
|
|
@ -719,7 +721,40 @@
|
||||||
<bpmn2:sequenceFlow id="sequenceFlow_ZTiO7w" sourceRef="event_zzWQSA" targetRef="task_Q80A1Q">
|
<bpmn2:sequenceFlow id="sequenceFlow_ZTiO7w" sourceRef="event_zzWQSA" targetRef="task_Q80A1Q">
|
||||||
<bpmn2:documentation id="documentation_S2i1Tg"/>
|
<bpmn2:documentation id="documentation_S2i1Tg"/>
|
||||||
</bpmn2:sequenceFlow>
|
</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:process>
|
||||||
|
<bpmn2:signal id="signal_1" name="com.alexanderlogistics.AGLAnalyticExcelAdapterDebitor"/>
|
||||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1" name="OpenBPMN Diagram">
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1" name="OpenBPMN Diagram">
|
||||||
<bpmndi:BPMNPlane bpmnElement="collaboration_1" id="BPMNPlane_1">
|
<bpmndi:BPMNPlane bpmnElement="collaboration_1" id="BPMNPlane_1">
|
||||||
<bpmndi:BPMNShape bpmnElement="event_WmkBvw" id="BPMNShape_heefeQ">
|
<bpmndi:BPMNShape bpmnElement="event_WmkBvw" id="BPMNShape_heefeQ">
|
||||||
|
|
@ -1070,6 +1105,18 @@
|
||||||
<di:waypoint x="714.0" y="465.0"/>
|
<di:waypoint x="714.0" y="465.0"/>
|
||||||
<di:waypoint x="690.0" y="465.0"/>
|
<di:waypoint x="690.0" y="465.0"/>
|
||||||
</bpmndi:BPMNEdge>
|
</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:BPMNPlane>
|
||||||
</bpmndi:BPMNDiagram>
|
</bpmndi:BPMNDiagram>
|
||||||
</bpmn2:definitions>
|
</bpmn2:definitions>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue