Compare commits

...

47 commits

Author SHA1 Message Date
97a6e86a11 verbesserter prompt 2026-08-21 10:29:23 +02:00
f2bd7210e6 upgrade 1.4 -> Brazil 2026-08-20 22:40:40 +02:00
3c5e5b0546 Merge branch 'office-alexander-logistics-1.4' 2026-08-20 21:43:42 +02:00
f06adc290c update 2026-08-20 21:41:19 +02:00
6721c2de9b update 2026-08-20 15:11:58 +02:00
2d3f98c15c clean up docu and junit tests 2026-08-20 11:05:28 +02:00
cfe1edb294 Merge commit '8309be5b39a6f1e8228626e667a0678cf908d304' into office-alexander-logistics-1.4 2026-08-20 11:03:36 +02:00
f96d1af5e7 Merge branch 'master' into office-alexander-logistics-1.4 2026-08-20 11:02:58 +02:00
8309be5b39 neue tax email brazil 2026-08-20 10:45:22 +02:00
e85840695c Merge branch 'master' of ssh://git.imixs.com/git/office-alexander-logistics 2026-08-19 14:54:37 +02:00
b6782448f9 wrong email 2026-08-19 14:54:22 +02:00
f942231066 neuer AGLAIInvoiceAdapter für auflösung von space.ref 2026-08-19 10:18:36 +02:00
99e138e685 model mit besseren historien text 2026-08-18 11:49:10 +02:00
44df91da9d model fix, backup testbackup test 2026-08-18 11:48:12 +02:00
8afb45271f cancel button added 2026-08-17 12:17:52 +02:00
7bca17dcca cancel button added 2026-08-17 12:17:04 +02:00
fe4ca105df fix gitignore 2026-08-17 11:35:41 +02:00
202fe2f3a0 korrektur validierung Gutschriften 2026-08-17 11:34:31 +02:00
3d322152e5 update neue AI Version 2026-08-17 11:22:38 +02:00
01e0e89e14 Migration office 2026-08-15 14:19:38 +02:00
e14af8449f migration auf neue office version 2026-08-15 10:54:26 +02:00
b8d0660526 neue KI Features 2026-08-15 09:46:17 +02:00
aeba05cc19 update polen 2026-08-13 12:23:06 +02:00
020498eee7 update sepa brasilien 2026-08-12 14:09:07 +02:00
6a66fd1852 fixed timing in ksef export 2026-08-07 18:01:01 +02:00
0a459e4b48 improved http check status mechanism 2026-08-04 12:12:17 +02:00
49c8ea0db9 New task Reklamiert/bezahlt 2026-07-31 12:30:09 +02:00
bd0500beef update cn und br 2026-07-31 12:13:13 +02:00
b6e56958ec logging, configuraiton BR 2026-07-27 20:03:05 +02:00
3f15b3a11b anapssungen der einvoice 2026-07-24 11:04:22 +02:00
f758c4a6ac verbesserungen e-invoice 2026-07-23 16:25:15 +02:00
0d9c9d8615 impvore e-invoice format 2026-07-23 16:13:44 +02:00
2b997da394 Setup AGL BR 2026-07-23 13:07:55 +02:00
092aa40ceb added timer to solve scheduler hangs 2026-07-17 09:40:51 +02:00
8d9de4a16a fixes error messages, added data export 2026-07-06 12:27:33 +02:00
1086466822 ksef update 2026-07-06 11:34:28 +02:00
a3df1a0a77 KSeF Docu 2026-06-29 22:31:39 +02:00
68acd25778 skip validation in end status-manuelle Auslandsrechnung 2026-06-29 13:42:09 +02:00
4e24e6e7b4 update 2026-06-26 12:28:38 +02:00
53703cdf9b purchase workflow 2026-06-24 11:26:56 +02:00
394297b31c new forward opiton 2026-06-11 18:32:05 +02:00
6a22dc29af update invoice worklow 2026-06-11 13:51:35 +02:00
38b60d7621 update payment.date 2026-06-10 15:06:11 +02:00
944d72b2cf minor fixes 2026-06-10 14:55:24 +02:00
f6fb26dcf0 fixes 2026-06-10 11:20:51 +02:00
4203572a8f upgrade 1.3.6 2026-06-08 12:20:09 +02:00
049bf8fea9 new dataview version 2026-06-08 12:19:48 +02:00
458 changed files with 127174 additions and 406577 deletions

2
.gitignore vendored
View file

@ -13,9 +13,11 @@ target/
.metadata/
.project
.classpath
.env
# ignore docker deployments
docker/deployments/
docker/keys/imixs-llm.xml
# Sepa Report
reports/sepa/result_sepa*

View file

@ -1,11 +1,7 @@
FROM imixs/imixs-office-workflow:5.1.1-wildfly-27.0.1.Final-jdk17
#FROM imixs/imixs-office-workflow:5.1.0
# Setup debug configuration
# COPY ./docker/configuration/standalone-debug.xml /opt/jboss/wildfly/standalone/configuration/
COPY ./docker/lucene-core-7.7.3.jar /opt/jboss/
FROM imixs/imixs-office-workflow:5.1.5-wildfly-29.0.1.Final-jdk17
# Deploy artefact
RUN rm -r /opt/jboss/wildfly/standalone/deployments/*
COPY ./*-app/target/*.war /opt/jboss/wildfly/standalone/deployments/
# Deploy artefact
COPY ./target/*.war /opt/jboss/wildfly/standalone/deployments/

View file

@ -1,10 +1,8 @@
FROM imixs/imixs-office-workflow:5.1.1-wildfly-27.0.1.Final-jdk17
#FROM imixs/imixs-office-workflow:5.1.0
FROM imixs/imixs-office-workflow:5.1.5-wildfly-29.0.1.Final-jdk17
# Deploy artefact
RUN rm -r /opt/jboss/wildfly/standalone/deployments/*
COPY ./*-app/target/*.war /opt/jboss/wildfly/standalone/deployments/
COPY ./target/*.war /opt/jboss/wildfly/standalone/deployments/
# Run in Debug Mode
CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0", "--debug", "*:8787"]

View file

@ -1,11 +1,25 @@
# Versionen
## KSeF Produktiname II.
## 1.4.0 (Development)
- neuer AGLAIInvoiceAdapter
der Adapter `com.alexanderlogistics.AGLAIInvoiceAdapter` muss künftig in das Import Event der Rechnungseingangs Modelle. Dieser Adapter Findet den Space und den Mandanten.
Neue Modelle:
- Posteingang
- posteingang-de-3.0
- AMS
- rechnungseingang-ams-1.1.0.bpmn
## 1.3.6 (Development)
**KSeF Produktiname II.**
Neues ksef.xml als Template einspielen
Neue version deployen.
## KSeF Produktiname I.
**KSeF Produktiname I.**
Wir bekommen von Majcie einen neuen Prod - Token für KSeF. Dieser muss in das Kubernetes Deployment file eintegragen werden. Auch der Enpunkt muss geändert werden!
@ -19,12 +33,10 @@ Wir bekommen von Majcie einen neuen Prod - Token für KSeF. Dieser muss in das K
Im Worklfow Modell 'rechnungsausgang' muss das das Partner Mail im Schritt 4200.10 aktiviert werden.
jhendzel@alexander-logistics.com in CC
ralph.soika@imixs.com in BCC
Derzeit fehlen meistens die Mailadressen so dass vermutlich häufig keine Mails rausgehen.
Im Dokument Import 'CARGOSOFT_INVOCIE_XML' muss die Task ID von 5001 auf 4000 geändert werden!!
## 1.3.5 (Development)
## 1.3.5
- Verbesserter Cargosoft Export (Eingangsrechnungen)
- Polen KSeF Schnittstelle

204
backup/README.md Normal file
View file

@ -0,0 +1,204 @@
# Eigenes Backup-System (Backup-Mirror)
## Architektur, Einrichtung und Disaster-Recovery-Konzept
---
## 1. Idee und Architektur
### 1.1 Ausgangslage
Imixs-Office-Workflow wird von uns als eine transaktionale, hochverfügbare
Geschäftsprozessmanagement-Suite betrieben. Die Basis ist ein Open Source Kernel,
der frei zugänglich ist ([https://github.com/imixs/](https://github.com/imixs/)).
Unabhängig vom gewählten Betriebsmodell (SaaS, Public Cloud, Private Cloud, On
Premise) sind und bleiben Sie Eigentümer Ihrer Geschäftsdaten. Über den
Backup-Service haben Sie die Möglichkeit, jederzeit eigenständig auf eine
vollständige Kopie Ihrer Daten zuzugreifen unabhängig davon, wie und wo Ihre
Instanz aktuell betrieben wird.
### 1.2 Architektur Own your Data
Auch wenn wir den Betrieb Ihrer Instanz übernehmen, bedeutet das nicht, dass Sie
von uns abhängig sind. Über den Backup-Mirror betreiben Sie bei sich einen eigenen,
unabhängigen Backup-Dienst. Dieser Dienst wird von Ihnen selbst eingerichtet,
verwaltet und überwacht und läuft vollständig autark wir müssen ihn technisch
weder kennen noch verwalten. Dadurch gilt:
> **Sie verfügen über eine eigenständige, vollständige Kopie Ihrer
> Geschäftsdaten unabhängig von unserer Infrastruktur. Mit dieser Kopie kann
> Ihr System bei Bedarf komplett neu aufgebaut werden.**
Das ist ein bewusst einfaches und robustes Prinzip: Es kommt nicht darauf an, *wo*
Ihre Daten zusätzlich liegen, sondern *wer* die Kontrolle über diesen zusätzlichen
Sicherungsort hat. Nur wenn diese Kontrolle bei Ihnen liegt, sind Sie wirklich
unabhängig.
### 1.3 Wie es funktioniert
Technisch basiert das Konzept auf dem Open-Source-Projekt
[Imixs-Archive](https://github.com/imixs/imixs-archive), konkret auf dem Baustein
*Imixs-Archive-Backup*. Der Ablauf im Überblick:
1. Bei jeder Änderung an einem Geschäftsvorgang erzeugt Ihre Workflow-Instanz
automatisch einen unveränderlichen Snapshot (eine vollständige Kopie des
Vorgangs inkl. aller angehängten Dokumente).
2. Diese Snapshots werden über die REST-Schnittstelle Ihrer Workflow-Instanz
bereitgestellt.
3. Ein bei Ihnen installierter Backup-Dienst (siehe Abschnitt 2) ruft diese
Snapshots eigenständig ab und speichert sie auf einem Speicherort Ihrer Wahl
(z. B. eigener FTP-/Storage-Server).
Wichtig: Die Verbindung erfolgt **von Ihrem System zu unserer Workflow-Instanz**
(„Pull-Prinzip"). Sie benötigen dafür lediglich einen Netzwerkzugriff auf die
REST-Schnittstelle Ihrer Instanz wir müssen keinen Zugriff auf Ihre Infrastruktur
haben und erhalten auch keinen.
---
## 2. Technische Einrichtung
Der Backup-Dienst kann als Docker-Container in unterschiedlichen Umgebungen betrieben werden:
- **Local**: lokal über Docker oder Docker Compose,
- **Private Cloud**: in einer Private Cloud (z.b. Kubernetes, OpenShift)
- **Public Cloud**: in einer Public Cloud Umgebung (z.b. AWS, Microsoft Azure)
### 2.1 Voraussetzungen
- Eine eigene Server- bzw. Container-Umgebung (Docker) auf Ihrer Seite
- Ein eigener Speicherort für die Backup-Daten (z. B. FTP-Storage, NAS mit
FTP-Anbindung)
- Eine sogenannte **Mirror-ID**, die wir Ihnen bereitstellen
### 2.2 Mirror-ID anfragen
Die Mirror-ID ist eine organisatorische Kennung, mit der wir Ihre eigene
Backup-Verbindung für Ihre Instanz freischalten. Sie ist kein Sicherheitsmerkmal im
engeren Sinn, sondern eine Vereinbarung zwischen uns: *„Kunde X betreibt ein eigenes
Backup."* Bitte fordern Sie diese ID formlos bei uns an.
### 2.3 Backup-Nutzer in Ihrer eigenen Instanz anlegen
Ein zentraler Punkt für die Autarkie des Systems: **Sie legen den technischen
Benutzer für den Backup-Zugriff selbst in Ihrer Imixs-Instanz an.** Dieser Nutzer
gehört ausschließlich Ihnen wir kennen weder das Passwort noch verwalten wir
dieses Konto. Vergeben Sie dem Nutzer ausreichende Leserechte, damit er alle
relevanten Vorgänge und Dokumente sichern kann.
### 2.4 Docker-Compose Beispielkonfiguration
Das folgende Beispiel zeigt eine Docker Compose Konfiguraiton für den Betrieb des Backup-Dienstes:
```yaml
version: "3.6"
services:
backup:
image: imixs/imixs-archive-backup:latest
environment:
TZ: "Europe/Berlin"
WORKFLOW_SERVICE_ENDPOINT: "https://<ihre-instanz>.office-workflow.de/api/"
WORKFLOW_SERVICE_USER: "<ihr-backup-nutzer>"
WORKFLOW_SERVICE_PASSWORD: "<ihr-passwort>"
WORKFLOW_SERVICE_AUTHMETHOD: "form"
BACKUP_FTP_HOST: "<ihr-storage-host>"
BACKUP_FTP_PATH: "<ihr-zielverzeichnis>"
BACKUP_FTP_PORT: "21"
BACKUP_FTP_USER: "<ihr-ftp-nutzer>"
BACKUP_FTP_PASSWORD: "<ihr-ftp-passwort>"
BACKUP_MIRROR_ID: "<ihre-mirror-id>"
ports:
- "8084:8080"
- "9990:9990"
```
**Erläuterung der wichtigsten Parameter:**
| Parameter | Bedeutung |
|---|---|
| `WORKFLOW_SERVICE_ENDPOINT` | Die REST-API-Adresse Ihrer bei uns gehosteten Workflow-Instanz |
| `WORKFLOW_SERVICE_USER/PASSWORD` | Der von Ihnen selbst angelegte Backup-Nutzer |
| `BACKUP_FTP_*` | Ihr eigener Speicherort für die Backup-Daten |
| `BACKUP_MIRROR_ID` | Die von uns bereitgestellte Freischalt-ID |
Nach dem Start prüft der Dienst regelmäßig auf neue zu sichernde Vorgänge und
überträgt diese automatisch auf Ihren Speicherort.
### 2.5 Monitoring des eigenen Backup-Dienstes
Da der Dienst vollständig in Ihrer Verantwortung läuft, sollten Sie ihn aktiv
überwachen. Ein einfacher Ping-Check zeigt zwar, dass der Container erreichbar
ist sagt aber nichts darüber aus, ob der Dienst tatsächlich funktionsfähig ist
und Backups erfolgreich durchführt.
Der Imixs-Archive-Backup-Service stellt hierfür standardisierte **MicroProfile-Endpunkte** mit, die auf Port `9990`
bereitgestellt werden:
| Endpunkt | Beschreibung |
|---|---|
| `/health` | Liefert den Health-Status des Dienstes nach dem MicroProfile-Health-Standard inklusive Readiness (ist der Dienst betriebsbereit, z. B. Verbindung zur Workflow-API und zum FTP-Storage vorhanden?) und Liveness (läuft der Prozess korrekt?) |
| `/metrics` | Liefert Betriebskennzahlen im MicroProfile-Metrics-Format (Prometheus-kompatibel), z. B. Anzahl verarbeiteter Backups, Fehlerzähler, Laufzeiten |
Damit lässt sich der Dienst professionell überwachen:
- **Health-Checks** binden Sie direkt in gängige Monitoring-Systeme ein (z. B.
Kubernetes Liveness-/Readiness-Probes, Uptime-Kuma, Nagios, Icinga) und erkennen
so nicht nur einen abgestürzten Container, sondern auch einen Dienst, der zwar
läuft, aber z. B. keine Verbindung mehr zu Ihrer Workflow-Instanz oder zum
FTP-Ziel herstellen kann.
- **Metrics** lassen sich direkt von Prometheus abgegriffen und in Grafana
visualisiert werden so erkennen Sie auf einen Blick, ob regelmäßig Backups
durchgeführt werden, oder ob z. B. die Fehlerrate ansteigt.
**Voraussetzung:** Sie müssen Port `9990` in Ihrer Docker-Umgebung entsprechend
freigeben bzw. mappen, damit Ihr Monitoring-System auf die Endpunkte zugreifen kann
(siehe Port-Mapping im Beispiel aus Abschnitt 2.4).
Ein Backup, das unbemerkt seit Wochen nicht mehr funktioniert, bietet keinen Schutz.
Die Überwachung über Health- und Metrics-Endpunkte ist daher ein integraler
Bestandteil des Konzepts, nicht optional.
---
## 3. Notfall- und Wiederherstellungsfall (Disaster Recovery)
Im Falle eines Disaster-Recovery-Prozesses stellen Sie uns Ihr Backup zur Verfügung, damit Ihr System auf dessen Basis wiederhergestellt werden kann. Dieser Abschnitt beschreibt das Vorgehen nur in Stichpunkten.
Die vollständige technische Dokumentation der
Imixs-Workflow-Architektur ist Open Source und öffentlich einsehbar unter
[github.com/imixs](https://github.com/imixs).
**Grundprinzip der Wiederherstellung:**
- Ihre gesicherten Snapshot-Daten liegen vollständig und unverändert in Ihrem
eigenen Speicher (FTP/Storage) vor.
- Diese Daten liegen in einem offenen, plattformunabhängigen XML-Format vor und
sind nicht an unsere konkrete Infrastruktur gebunden.
- Auf Basis dieser Daten kann eine neue Imixs-Workflow-Instanz (bei Ihnen oder bei
einem anderen Dienstleister) aufgesetzt werden.
- Über die Restore-Funktion der Imixs-Archive-Komponenten werden die Snapshots in
die neue Instanz zurückgespielt jeder Geschäftsvorgang wird dabei inklusive
seiner Historie und aller Dokumente wiederhergestellt.
**Wichtige Stichpunkte für den Ernstfall:**
- Backup-Daten sind vollständig bei Ihnen vorhanden → keine Abhängigkeit von uns
- Wiederherstellung erfordert eine lauffähige Imixs-Workflow-Umgebung (Open Source,
frei verfügbar)
- Die technische Vorgehensweise zum Restore ist Teil der öffentlichen
Imixs-Archive-Dokumentation
- Wir unterstützen Sie im Ernstfall selbstverständlich gerne beim Wiederaufbau
diese Unterstützung ist jedoch **keine Voraussetzung**, da die Daten und das
Wiederherstellungsverfahren vollständig unabhängig von uns nutzbar sind
---
## 4. Zusammenfassung
Mit dem Backup-Mirror bleiben Sie jederzeit Eigentümer Ihrer Geschäftsdaten unabhängig
davon, wie und wo Ihre Instanz betrieben wird. Sie richten den Dienst selbst ein, verwalten
ihn eigenständig und behalten so die volle Kontrolle über Ihre zusätzliche Datenkopie. Genau
diese Unabhängigkeit ist es, die Ihnen im Bedarfsfall den vollständigen Wiederaufbau Ihres
Systems ermöglicht.
Bei Fragen zur Einrichtung oder zur Anforderung Ihrer Mirror-ID kontaktieren Sie uns
gerne.

View file

@ -0,0 +1,22 @@
version: "3.6"
services:
###############################################
# Backup Service
###############################################
backup:
image: imixs/imixs-archive-backup:latest
environment:
TZ: "Europe/Berlin"
WORKFLOW_SERVICE_ENDPOINT: "https://alexander-logistics-ams.office-workflow.de/api/"
WORKFLOW_SERVICE_USER: "kutzner-backup-service"
WORKFLOW_SERVICE_PASSWORD: "16e-7ede-4c1c-bdeb-e16ce"
WORKFLOW_SERVICE_AUTHMETHOD: "form"
BACKUP_FTP_HOST: "u248962.your-storagebox.de"
BACKUP_FTP_PATH: "/test/agl/ams-test"
BACKUP_FTP_PORT: "21"
BACKUP_FTP_USER: "u248962"
BACKUP_FTP_PASSWORD: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
BACKUP_MIRROR_ID: "backup-mirror-local"
WORKFLOW_REST_JPQL_DOUBLEDECODE_WORKAROUND: "true"
ports:
- "8084:8080"

4
devi
View file

@ -53,15 +53,13 @@ fi
if [[ "$(strip_dash $1)" == "hot" ]]; then
echo "* Hotdeploy..."
cd *-app
mvn manik-hotdeploy:hotdeploy
cd ..
fi
if [[ "$(strip_dash $1)" == "deploy" ]]; then
echo " Deploy to Imixs-Cloud..."
mvn clean install -Pkubernetes -DskipTests
mvn clean install -Pimixs-cloud -DskipTests
fi

View file

@ -1,96 +0,0 @@
# FTP Server
Wir stellen verschiedene FTP Laufwerke auf dem Hetzner bereit um Daten mit Cargosoft und anderen Partnern auszutauschen
# Cargosoft
**ACHTUNG:** Frau Beste bittet darum den public key für alle Sub Accounts zu installieren:
$ cat id_rsa_cargosoft.pub | ssh -p23 u248962-sub12@u248962.your-storagebox.de install-ssh-key
## Cargosoft Schnittstelle (Bremen - Mandant 001)
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft
Benutzername: u248962-sub2
Passwort: aXa61n9Un3jDNQlL
## Cargosoft Schnittstelle (AMS - Mandant 002)
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft-ams
Benutzername: u248962-sub12
Passwort: RA9N0V8EB8_1Dnw
## Cargosoft Schnittstelle (Bremerhaven Mandant 005)
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft-bhv
Benutzername: u248962-sub5
Passwort: 5hKKzv6TFCKRrAdR
## Cargosoft Schnittstelle (Polen Mandant 003)
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft-pl
Benutzername: u248962-sub7
Passwort: PGPzzqmtZ8BSxkbs
## Cargosoft Schnittstelle (Dubai Mandant 006)
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft-dwc
Benutzername: u248962-sub3
Passwort: enHjxs9h4nJ6EgsZ
## Cargosoft Schnittstelle (USA Mandant 004)
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft-usa
Benutzername: u248962-sub9
Passwort: GMk7NgDBrmb2QqXg
## Cargosoft Schnittstelle (China Mandant 007)
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft-chn
Benutzername: u248962-sub10
Passwort: yswBeN83jMqkMqJa
# Dubai
**ACHTUNG** Wird nicht merh genutzt - jetzt Zoho
Wir stellen Herrn Hoelzl in Dubai ein eigenes FTP Laufwerk bereit, in das wir die Rechnungen per Imixs-Exporter verschieben.
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/filetransfer-dwc
Benutzername: u248962-sub11
Passwort: mH9mAS77QhuA5XJi
Herr Hoelzl überträgt dann die Daten in eine app von einer Steuerkanzlei.
Es wird dazu ein FTP Server bereitgestellt der von Herrn Hölzl und Frau Geisler lokal eingebunden werden kann.
Der aktuelle Workflow für Eingangs- und Ausgangsrechnungen wird dahingehend angepasst, dass die Belege automatisch nach folgenden Format exportiert werden:
```
├── invoice-out
│ ├── 2024
│ │ ├── 06
│ │ │ ├── 198_EX-DWC-2406-013.pdf
│ │ │ ├── 199_EX-DWC-2406-013.pdf
│ │ ├── 07
│ │ │ ├── 200_IM-DWC-2407-010.pdf
├── invoice-in
│ ├── 2024
│ │ ├── 06
│ │ │ ├── 700045_EX-DWC-2406-005.pdf
│ │ │ ├── 700045_59475.pdf
```
sequencenumer +
firmename + positionsnummer + rechnungsnummer +
Der Export erfolgt automatisch nach Empfang der Rechnung bzw. nach Prüfung der Rechnung (Review->Approved). Die Dateinamen werden vom System berechnet (siehe oben). Bei Sachrechnungen wird das Rechnungsdatum verwendet um die Buchungsperiode zu berechnen.

View file

@ -1,49 +0,0 @@
Hallo,
wir nutzen oben genannte Storage Box für den Datenaustausch mit verschiedenen Kunden.
Einer der Kunden kann seit dem 25. Juli nicht mehr von seinem Firmennetzwerk darauf zugreifen.
Wir haben auf dem Linux Server beim Kunden folgende Tests durchgeführt:
cargodb@cargodb:~$ sftp -v -oPort=22 u248962-sub1@u248962.your-storagebox.de
OpenSSH_8.2p1 Ubuntu-4ubuntu0.3, OpenSSL 1.1.1f 31 Mar 2020
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/_.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for _
debug2: resolving "u248962.your-storagebox.de" port 22
debug2: ssh_connect_direct
debug1: Connecting to u248962.your-storagebox.de [78.47.94.120] port 22.
debug1: connect to address 78.47.94.120 port 22: Connection refused
debug1: Connecting to u248962.your-storagebox.de [2a01:4f8:2b01:db::2] port 22.
debug1: connect to address 2a01:4f8:2b01:db::2 port 22: Network is unreachable
ssh: connect to host u248962.your-storagebox.de port 22: Network is unreachable
Connection closed.
cargodb@cargodb:~$ nc -zv u248962-sub1@u248962.your-storagebox.de 22
nc: getaddrinfo for host u248962-sub1@u248962.your-storagebox.de port 22: Name or service not known
cargodb@cargodb:~$ tcptraceroute u248962.your-storagebox.de 22
Selected device ens160, address 192.168.83.3, port 52113 for outgoing packets
Tracing the path to u248962.your-storagebox.de (78.47.94.120) on TCP port 22 (ssh), 30 hops max
1 192.168.83.254 0.233 ms 0.175 ms 0.242 ms
2 82-198-218-38.briteline.de (82.198.218.38) 1.470 ms 1.103 ms 2.286 ms
3 10.200.48.254 0.930 ms 0.915 ms 0.776 ms
4 82-198-192-194.briteline.de (82.198.192.194) 1.092 ms 1.114 ms 0.902 ms
5 82-198-216-168.briteline.de (82.198.216.168) 1.101 ms 1.168 ms 1.034 ms
6 ae0-201.cr11.bre04.lwlcom.net (31.209.93.121) 1.543 ms 1.650 ms 1.528 ms
7 ae0-30.cr10.bre09.lwlcom.net (185.146.230.97) 7.713 ms 7.440 ms 11.215 ms
8 ae0-10.cr11.bre09.lwlcom.net (185.146.230.53) 7.647 ms 7.652 ms 7.617 ms
9 ae0-20.cr10.bre03.lwlcom.net (185.146.230.99) 7.530 ms 7.716 ms 7.505 ms
10 ae7-90.cr10.bre11.lwlcom.net (185.146.230.34) 7.723 ms 7.661 ms 7.578 ms
11 ae7-100.cr10.lut01.lwlcom.net (185.146.230.39) 7.446 ms 7.509 ms 7.673 ms
12 ae6-100.cr10.fra03.lwlcom.net (185.146.230.27) 7.980 ms 7.281 ms 7.981 ms
13 ae2-100.cr10.fra04.lwlcom.net (185.146.230.51) 7.287 ms 7.392 ms 7.406 ms
14 213-133-121-205.clients.your-server.de (213.133.121.205) 10.464 ms 10.542 ms 10.573 ms
15 core24.fsn1.hetzner.com (213.239.224.85) 16.458 ms 16.381 ms 16.338 ms
16 mx10k1.dc3.fsn1.hetzner.com (213.239.254.142) 16.632 ms 16.687 ms 24.837 ms
17 static.120.94.47.78.clients.your-server.de (78.47.94.120) 16.526 ms !p 16.509 ms !p 16.505 ms !p
Können Sie anhand dieser Daten erkennen worin das Problem besteht? Andere Kunden können die Storage Box problemlos nutzen.
Vielen Dank für Ihre Hilfe
Mit freundlichen Grüßen
Ralph Soika

View file

@ -1,25 +0,0 @@
# Feedback zum PDF FIle
| Feld / Komponente | Status |
| :------------------------------------------------------- | :----------------------- |
| **1. Podmiot 1 — Daten des Rechnungsausstellers (AGLP)** | |
| `<Nazwa>` | **FIXED** |
| `<AdresL1>` | **FIXED** |
| `<PrefiksPodatnika>PL</PrefiksPodatnika>` | **FIXED** |
| **2. Podmiot 2 — Daten des Rechnungsempfängers** | |
| `<NrID> <NIP>` | **ALREADY IMPLEMENTED** |
| EU-Rechnungsempfänger | **UNCLEAR!** |
| Anschrift des Rechnungsempfängers | **CARGOSOFT TOPIC** |
| **3. Abschnitt <Fa> — Rechnungskopf** | **FIXED** |
| `<P_1M>` | **FIXED** |
| `<KursWalutyZ>` | **FIXED** |
| **4. Rechnungspositionen <FaWiersz> — Pflichtfelder** | |
| `<P_7>` | **FIXED** |
| `<P_8B>` | **IGNORED - NOT FIXED!** |
| `<P_11A>` | **????** |
| `<P_11Vat>` | **????** |
| **5. Rechnungssummen — <P_13_x> / <P_14_x>** | |
| _Noch keine Details_ | — |
| **6. Zahlung — <Platnosc>** | |
| `<FormaPlatnosci>` | **FIXED** |
| `<RachunekBankowy>` | **FIXED** |

View file

@ -1,3 +0,0 @@
NIP = "9552521552"
TOKEN = "20251113-EC-2751AC3000-5C5466924B-62|nip-9552521552|fc0c95d020dc45d4af491fb0aa755f3f3f674b33ecbf4250a88ea6e36fa8340b

View file

@ -1,9 +0,0 @@
# Mail
Testen von Mailing kann man über
https://www.mail-tester.com/
Kutzner Mail gateway
PW: 26W%R#Xe4^Z2Gyz1

View file

@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnGiu0PUBl+G++vHrGP5wDRit4mXF4hXTyzUem3BPADaV0DUuYN1Fx5RpDl2F8mhnqDYcyCTBzLTJ+0jFqq1pzoJW5ZWZ+hSChabVCV4m8UkFkhbRmjxNkPx26ZMhfTD1mDqgCKQ+bbt1mi04UZppDKBr+9ZrMG3d0odHblEJHixtJ7Hqr9vvXXbvNv4E9B/9dlW57oyEUk/vKmwuLyGAsDjxjfB3W+Faab+gev8VDwJxdbD90HX0O2Az05wy9EC7M3pujcawsHdaFXgFFRRwlVuUkX3z9hp1Uekqg0N81hty7/i8GiZ9/m3Y6hIA5eRM4ZpDQFEF8SY9TLSzDehNoQ== seesped@cargodb

View file

@ -1,78 +0,0 @@
# 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
```
zoho.accesstoken 1000.18f5fbeaf572425b8062d015d541aad5.a704efa994774ef33d7af75106468a13
zoho.apidomain https://www.zohoapis.eu
zoho.clientid 1000.GR5FTPZYB06HEWSFSSX4DJU3OBD4EJ
zoho.clientsecret 3f3e74c5212bbc924a7ebf77f887c6296db1106c47
zoho.code 1000.c184c7592a218fee58f7b7855b56eb77.7b533ff9f570fd6ab3296784caeec072
zoho.organization 20105697367
zoho.refreshtoken 1000.98fe4d0c4f676237b400bf8a3dc219f3.03d6bacf5b988d339eb788c4ecff440e
zoho.scope ZohoBooks.contacts.ALL ZohoBooks.invoices.CREATE ZohoBooks.invoices.READ ZohoBooks.invoices.UPDATE
```
## Atari
atari.600xl@gmail.com
800xlAtari
```
zoho.apidomain https://www.zohoapis.eu
zoho.clientid 1000.86O4P321HDYDRX0Q0N1G7YOJRJ9D5W
zoho.clientsecret 2a67b6cfc364f5df27cc8eb33e9b0e4e8a0221ebc3
zoho.code 1000.c7dc89c06111b93f1242b587fabed4ac.44c591dffbd978a316e3d90ed3fefc78
zoho.organization 886924765
zoho.scope ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
```
## Prod DWC
info@imixs.com
imixs4zoho
Für Drecks Forum
Imixs4#zoho
Imixs4#zoho
http://books.zoho.com/
https://api-console.zoho.com/
ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
```
zoho.apidomain https://www.zohoapis.com
zoho.clientid 1000.MQE1SU8UGY6F2PBPASOXGTLWYQD1FS
zoho.clientsecret 1ca70e1ab803b3fed6b1b5e00858c316e2003d289b
zoho.organization 884218508
zoho.scope ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
```
# 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/
# AGL Organisation
https://api-console.zoho.com
info@imixs.com
password imixs4zoho

View file

@ -25,7 +25,7 @@ services:
POSTGRES_CONNECTION: "jdbc:postgresql://db/office-alexander-logistics"
TZ: "CET"
LANG: "en_US.UTF-8"
MAILGATEWAY: "mailgateway"
MAILGATEWAY: "mailpit"
ASYNCEVENT_PROCESSOR_ENABLED: "true"
ASYNCEVENT_PROCESSOR_INITIALDELAY: "10000"
@ -41,8 +41,8 @@ services:
WORKFLOW_SERVICE_USER: "admin"
WORKFLOW_SERVICE_PASSWORD: "adminadmin"
LLM_SERVICE_ENDPOINT_USER: "admin"
LLM_SERVICE_ENDPOINT_PASSWORD: "imixs4.null"
# LLM Integration
LLM_CONFIG_FILE: /opt/jboss/imixs-llm.xml
# KSeF - Polen Test
KSEF_API_NIP: "9552521552"
@ -57,6 +57,7 @@ services:
- "8787:8787"
volumes:
- ./docker/deployments:/opt/jboss/wildfly/standalone/deployments/
- ./docker/keys/imixs-llm.xml:/opt/jboss/imixs-llm.xml
- ./docker/transfer:/opt/jboss/wildfly/transfer/
###############################################
@ -102,12 +103,15 @@ services:
###############################################
# Mailgateway
###############################################
mailgateway:
image: imixs/exim4
mailpit:
image: axllent/mailpit:latest
container_name: mailpit
environment:
EXIM_SMARTHOST: "www149.your-server.de:25"
EXIM_PASSWORD: "www149.your-server.de:webmaster@imixs.com:$MAILPASSWORD"
EXIM_ALLOWED_SENDERS: "10.0.0.0/8:172.18.0.0/12:192.168.0.0/16"
MP_SMTP_BIND_ADDR: "0.0.0.0:25"
ports:
- "1025:25" # Host:1025 -> Container:25 (SMTP)
- "8025:8025" # Web UI
restart: unless-stopped
# prometheus:
# image: prom/prometheus:latest

4
docker/.env Normal file
View file

@ -0,0 +1,4 @@
# LLM Config
LLM_API_ENDPOINT=https://api.llama.cpp.imixs.com/
LLM_API_KEY=7fdb663fa87ea16731c1e0ece8ad3214e358423eabf2403188110c731ce07321

55
docker/keys/imixs-llm.xml Normal file
View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
imixs-llm.xml - LLM Model Registry
======================================
Place this file in your deployment so it is available on the classpath,
e.g. in src/main/resources/ for a Maven project.
Each <model> element defines one logical LLM service endpoint.
A model is either a completion model OR an embedding model - never both.
The BPMN configuration references them separately by their id:
<imixs-ai name="CONDITION">
<endpoint>my-llm</endpoint>
...
</imixs-ai>
<imixs-ai name="RAG_INDEX">
<endpoint-completion>my-llm</endpoint-completion>
<endpoint-embeddings>my-embeddings</endpoint-embeddings>
...
</imixs-ai>
Environment variable placeholders are supported via ${env.VAR_NAME}.
-->
<imixs-llm>
<!--
Completion model used for chat completions, conditions, analysis etc.
This example connects to a local llama.cpp server.
-->
<endpoint id="api.llama.cpp.imixs.com">
<url>https://api.llama.cpp.imixs.com/</url>
<apikey>7fdb663fa87ea16731c1e0ece8ad3214e358423eabf2403188110c731ce07321</apikey>
<options>{
"temperature": 0.2,
"max_tokens": 1024
}
</options>
</endpoint>
<!--
Embedding model used for RAG indexing and retrieval.
This example connects to a separate embedding server.
No apikey needed for a locally hosted instance.
-->
<endpoint id="embeddings.llama.cpp.imixs.com">
<url>https://embeddings.llama.cpp.imixs.com/</url>
<apikey>7fdb663fa87ea16731c1e0ece8ad3214e358423eabf2403188110c731ce07321</apikey>
<options>{
"max_tokens": 512
}
</options>
</endpoint>
</imixs-llm>

Binary file not shown.

View file

@ -1,11 +0,0 @@
#!/bin/bash
############################################################
# Setup hotdeploy
#
############################################################
cd office-alexander-logistics-app
mvn manik-hotdeploy:hotdeploy
cd ..

View file

@ -1,53 +0,0 @@
# ML Models
Wir verwenden bei Alexander-Global Logistics ein standard Invoice ML Modell. Dieses basiert im Grund auf unserem offizielen spacy modell 'invoice-de-0.1.0'.
## Modell Nachtrainieren
Das Modell bei Alexander Logistics läst sich in der Dev Umggebung bei Bedarf nachtrainieren. Dazu geht man wie folgt vor:
**1.)** Aktuelles Modell auf Tikal Cloud Server sichern:
$ ssh imixs@master-1.tikal.imixs.com
$ cd tikal-cloud/
$ ./apps/alexander-logistics.office-workflow.de/ml_model_backup.sh
# Falls es zu einem io/error kommt, muss der spacy ml pod neu gestartet werden!
**2.)** Die Tikal-Cloud Pullen
**3.)** Um auf dem aktuellen Modell weiter zu trainierne, den Inhalt des invoice-de-0.1.0 Folders aus dem Backup directory in die lokale Dev Umgebung kopieren /
um ein neues Modell zu genereiren einfach den localen ordner 'invoice-de-0.1.0' umbenennen oder leeren.
**4.)** Jetzt lokal den Trainingsserver aufrufen
http://localhost:8081/api/openapi-ui/index.html
und das training beginnen mit der datei 'training-config-prod.xml'. Man kann das training 3-4 mal durchführen.
**5.)** Nun kann man die Inhalte des invoice-de-0.1.0 Folders zurück auf den Tikal in den modell folder /invoice-de-0.1.0 einspielen
**6.)** Nun die änderungen nach Git Puschen.
**7.)** auf dem Tikal Sever nun das aktuellisete Modell wieder einspielen
$ git pull
$ ./apps/alexander-logistics.office-workflow.de/ml_model_deploy.sh invoice-de-0.1.0/
## 22.05.2021 - invoice-de-0.1.0
NER=2.1948
## 17.02.2020 - invoice-de-0.1.0
Modell trainiert anhand der alexander-logistics Produtiv daten

View file

@ -1,491 +0,0 @@
# Test Protokoll Alexander Logistic invoice-de-0.1.0
**Validierung**
f4eaceda-f28a-4394-928e-1a05daaf2760
a5d1e7fe-d74a-4fa2-9b06-3221865759fa
c0290497-f613-4492-81b6-4ae1e1680029
d8e3fce4-d11c-46a4-8ba0-369b4c6e902f
8b766f35-828a-41f1-be04-00b4b62da4d0
**********************************************************************
** invoice-de-0.1.0-falsemodell
**12.10.2021 15:50** (sort order created)
**********************************************************************
workflow.query ($workflowgroup:"Rechnungseingang" OR $workflowgroup:"Sachrechnung") AND ($taskid:5900)
workflow.pagesize 500
ml.training.filepattern .pdf
ml.training.iterations 10
ml.training.dropoutrate 0,25
multiOccurrence false
ml.training.quality LOW
min_losses 0
RESULT
-----------------------------------------------------------------------
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 53.33% (200)
imixs-ml-training_1 | ...... quality level LOW = 31.47% (118)
imixs-ml-training_1 | ...... quality level BAD = 15.2% (57)
imixs-ml-training_1 | ...... average NER = 17.195895012525614
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 51.73% (194)
imixs-ml-training_1 | ...... quality level LOW = 32.8% (123)
imixs-ml-training_1 | ...... quality level BAD = 15.47% (58)
imixs-ml-training_1 | ...... average NER = 6.50170386961344
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 53.87% (202)
imixs-ml-training_1 | ...... quality level LOW = 31.73% (119)
imixs-ml-training_1 | ...... quality level BAD = 14.4% (54)
imixs-ml-training_1 | ...... average NER = 4.8940276912225
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 52.8% (198)
imixs-ml-training_1 | ...... quality level LOW = 32% (120)
imixs-ml-training_1 | ...... quality level BAD = 15.2% (57)
imixs-ml-training_1 | ...... average NER = 3.9605563888416824
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 54.13% (203)
imixs-ml-training_1 | ...... quality level LOW = 29.6% (111)
imixs-ml-training_1 | ...... quality level BAD = 16.27% (61)
imixs-ml-training_1 | ...... average NER = 3.744507591826106
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 53.07% (199)
imixs-ml-training_1 | ...... quality level LOW = 31.2% (117)
imixs-ml-training_1 | ...... quality level BAD = 15.73% (59)
imixs-ml-training_1 | ...... average NER = 2.8395576715820736
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 53.87% (202)
imixs-ml-training_1 | ...... quality level LOW = 32% (120)
imixs-ml-training_1 | ...... quality level BAD = 14.13% (53)
imixs-ml-training_1 | ...... average NER = 2.6799682681142363
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 53.6% (201)
imixs-ml-training_1 | ...... quality level LOW = 31.47% (118)
imixs-ml-training_1 | ...... quality level BAD = 14.93% (56)
imixs-ml-training_1 | ...... average NER = 2.520244211218683
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 49.33% (185)
imixs-ml-training_1 | ...... quality level LOW = 34.93% (131)
imixs-ml-training_1 | ...... quality level BAD = 15.73% (59)
imixs-ml-training_1 | ...... average NER = 2.1511980661715193
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 53.87% (202)
imixs-ml-training_1 | ...... quality level LOW = 31.2% (117)
imixs-ml-training_1 | ...... quality level BAD = 14.93% (56)
imixs-ml-training_1 | ...... average NER = 2.2739690429824475
**13.10.2021 12:00**
workflow.query ($workflowgroup:"Rechnungseingang" OR $workflowgroup:"Sachrechnung") AND ($taskid:5900)
workflow.pagesize 500
ml.training.filepattern .pdf|.PDF
ml.training.iterations 10
ml.training.dropoutrate 0,25
multiOccurrence false
ml.training.quality LOW
min_losses 0
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 61.33% (230)
imixs-ml-training_1 | ...... quality level LOW = 38.67% (145)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 3.790466332166552
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 61.07% (229)
imixs-ml-training_1 | ...... quality level LOW = 38.93% (146)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 3.160620521438082
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 58.13% (218)
imixs-ml-training_1 | ...... quality level LOW = 41.87% (157)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.636420357788331
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 58.13% (218)
imixs-ml-training_1 | ...... quality level LOW = 41.87% (157)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.506552163520219
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 58.93% (221)
imixs-ml-training_1 | ...... quality level LOW = 41.07% (154)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.3495061575286793
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 59.47% (223)
imixs-ml-training_1 | ...... quality level LOW = 40.53% (152)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.9351332692220107
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 61.33% (230)
imixs-ml-training_1 | ...... quality level LOW = 38.67% (145)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.8881396005118698
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 57.87% (217)
imixs-ml-training_1 | ...... quality level LOW = 42.13% (158)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.9754112840739593
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 59.73% (224)
imixs-ml-training_1 | ...... quality level LOW = 40.27% (151)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.7839739270522237
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 59.73% (224)
imixs-ml-training_1 | ...... quality level LOW = 40.27% (151)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.6024293913431429
**********************************************************************
** invoice-de-0.1.0
**12.10.2021 15:50** (sort order created)
**********************************************************************
workflow.query ($workflowgroup:"Rechnungseingang" OR $workflowgroup:"Sachrechnung") AND ($taskid:5900)
workflow.pagesize 500
ml.training.filepattern .pdf|.PDF
ml.training.iterations 10
ml.training.dropoutrate 0,25
multiOccurrence true
ml.training.quality LOW
min_losses 0
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68.27% (256)
imixs-ml-training_1 | ...... quality level LOW = 31.47% (118)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 21.57255353509432
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 67.73% (254)
imixs-ml-training_1 | ...... quality level LOW = 32.27% (121)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 8.249835149395697
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68.53% (257)
imixs-ml-training_1 | ...... quality level LOW = 31.2% (117)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 5.892598287488733
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68.53% (257)
imixs-ml-training_1 | ...... quality level LOW = 31.2% (117)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 4.964129124089013
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68.53% (257)
imixs-ml-training_1 | ...... quality level LOW = 31.2% (117)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 3.5603186705177947
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 67.2% (252)
imixs-ml-training_1 | ...... quality level LOW = 32.53% (122)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 2.692053828307031
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68% (255)
imixs-ml-training_1 | ...... quality level LOW = 31.73% (119)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 2.3509401762802873
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 65.87% (247)
imixs-ml-training_1 | ...... quality level LOW = 34.13% (128)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.2695994889458104
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68.27% (256)
imixs-ml-training_1 | ...... quality level LOW = 31.47% (118)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 1.844410364015416
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 70.67% (265)
imixs-ml-training_1 | ...... quality level LOW = 29.07% (109)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (1)
imixs-ml-training_1 | ...... average NER = 1.6153951610034658
page=1 (count=500)
--------------------------------
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 69.6% (261)
imixs-ml-training_1 | ...... quality level LOW = 30.4% (114)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 7.093659738880595
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 66.4% (249)
imixs-ml-training_1 | ...... quality level LOW = 33.6% (126)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 5.201780406598962
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68.27% (256)
imixs-ml-training_1 | ...... quality level LOW = 31.73% (119)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 3.8116329003426204
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 66.67% (250)
imixs-ml-training_1 | ...... quality level LOW = 33.33% (125)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 3.3164488404836154
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 66.93% (251)
imixs-ml-training_1 | ...... quality level LOW = 33.07% (124)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.7822570929398576
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 69.07% (259)
imixs-ml-training_1 | ...... quality level LOW = 30.93% (116)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.31773083524846
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 68.8% (258)
imixs-ml-training_1 | ...... quality level LOW = 31.2% (117)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.165804551920185
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 66.4% (249)
imixs-ml-training_1 | ...... quality level LOW = 33.6% (126)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.9591955652007715
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 66.4% (249)
imixs-ml-training_1 | ...... quality level LOW = 33.6% (126)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.5473874007025803
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 375
imixs-ml-training_1 | ...... quality level GOOD = 65.87% (247)
imixs-ml-training_1 | ...... quality level LOW = 34.13% (128)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 1.705957084193204
imixs-ml-training_1 | |#]
imixs-ml-training_1 |
page=0 (count=1000)
--------------------------------
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 67.47% (506)
imixs-ml-training_1 | ...... quality level LOW = 32.53% (244)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 3.2147245242951565
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 68.8% (516)
imixs-ml-training_1 | ...... quality level LOW = 31.07% (233)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 2.2084385109690565
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 67.73% (508)
imixs-ml-training_1 | ...... quality level LOW = 32.27% (242)
imixs-ml-training_1 | ...... quality level BAD = 0% (0)
imixs-ml-training_1 | ...... average NER = 2.1797281610496464
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 67.2% (504)
imixs-ml-training_1 | ...... quality level LOW = 32.67% (245)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.8908819163368502
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 66% (495)
imixs-ml-training_1 | ...... quality level LOW = 33.87% (254)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.7774978150912477
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 67.6% (507)
imixs-ml-training_1 | ...... quality level LOW = 32.27% (242)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.669098427922433
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 67.33% (505)
imixs-ml-training_1 | ...... quality level LOW = 32.53% (244)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.6048149396167861
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 67.6% (507)
imixs-ml-training_1 | ...... quality level LOW = 32.27% (242)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.4026393956412981
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 67.87% (509)
imixs-ml-training_1 | ...... quality level LOW = 32% (240)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.1139796046407426
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 65.87% (494)
imixs-ml-training_1 | ...... quality level LOW = 34% (255)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.2621875029460226
page=1 (count=1000)
--------------------------------
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 63.47% (476)
imixs-ml-training_1 | ...... quality level LOW = 36.4% (273)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 3.7501272727903876
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 64% (480)
imixs-ml-training_1 | ...... quality level LOW = 35.87% (269)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 2.7749715296165482
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 65.47% (491)
imixs-ml-training_1 | ...... quality level LOW = 34.27% (257)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 2.191986221088383
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 63.2% (474)
imixs-ml-training_1 | ...... quality level LOW = 36.53% (274)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.836000005105162
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 64.8% (486)
imixs-ml-training_1 | ...... quality level LOW = 34.93% (262)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.629252182245437
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 64.27% (482)
imixs-ml-training_1 | ...... quality level LOW = 35.47% (266)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.5023185259959349
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 63.6% (477)
imixs-ml-training_1 | ...... quality level LOW = 36.13% (271)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.1618358977500587
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 64.93% (487)
imixs-ml-training_1 | ...... quality level LOW = 34.93% (262)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.1362052688492958
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 64.4% (483)
imixs-ml-training_1 | ...... quality level LOW = 35.33% (265)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.0497074333838767
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 65.33% (490)
imixs-ml-training_1 | ...... quality level LOW = 34.4% (258)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 0.8865013575787167
page=1 (count=1000)
--------------------------------
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 63.33% (475)
imixs-ml-training_1 | ...... quality level LOW = 36.4% (273)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.6325150460009787
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 61.73% (463)
imixs-ml-training_1 | ...... quality level LOW = 38% (285)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.5385085364524884
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 63.6% (477)
imixs-ml-training_1 | ...... quality level LOW = 36.13% (271)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.343965340697668
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 64.13% (481)
imixs-ml-training_1 | ...... quality level LOW = 35.73% (268)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 1.1842750119930687
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 63.73% (478)
imixs-ml-training_1 | ...... quality level LOW = 36% (270)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 1.112559219903824
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 62.8% (471)
imixs-ml-training_1 | ...... quality level LOW = 36.93% (277)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 0.9444137586901881
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 64% (480)
imixs-ml-training_1 | ...... quality level LOW = 35.73% (268)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 0.9175624525798468
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 63.47% (476)
imixs-ml-training_1 | ...... quality level LOW = 36.27% (272)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 0.8877949306723629
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 62.53% (469)
imixs-ml-training_1 | ...... quality level LOW = 37.2% (279)
imixs-ml-training_1 | ...... quality level BAD = 0.27% (2)
imixs-ml-training_1 | ...... average NER = 0.7669201996298972
imixs-ml-training_1 |
imixs-ml-training_1 | ......documents trained in total = 750
imixs-ml-training_1 | ...... quality level GOOD = 62.8% (471)
imixs-ml-training_1 | ...... quality level LOW = 37.07% (278)
imixs-ml-training_1 | ...... quality level BAD = 0.13% (1)
imixs-ml-training_1 | ...... average NER = 0.7161310708827515

View file

@ -1,128 +0,0 @@
[paths]
train = null
dev = null
vectors = null
init_tok2vec = null
[system]
seed = 0
gpu_allocator = null
[nlp]
lang = "de"
pipeline = ["ner"]
disabled = []
before_creation = null
after_creation = null
after_pipeline_creation = null
batch_size = 1000
tokenizer = {"@tokenizers":"spacy.Tokenizer.v1"}
[components]
[components.ner]
factory = "ner"
incorrect_spans_key = null
moves = null
scorer = {"@scorers":"spacy.ner_scorer.v1"}
update_with_oracle_cut_size = 100
[components.ner.model]
@architectures = "spacy.TransitionBasedParser.v2"
state_type = "ner"
extra_state_tokens = false
hidden_width = 64
maxout_pieces = 2
use_upper = true
nO = null
[components.ner.model.tok2vec]
@architectures = "spacy.HashEmbedCNN.v2"
pretrained_vectors = null
width = 96
depth = 4
embed_size = 2000
window_size = 1
maxout_pieces = 3
subword_features = true
[corpora]
[corpora.dev]
@readers = "spacy.Corpus.v1"
path = ${paths.dev}
gold_preproc = false
max_length = 0
limit = 0
augmenter = null
[corpora.train]
@readers = "spacy.Corpus.v1"
path = ${paths.train}
gold_preproc = false
max_length = 0
limit = 0
augmenter = null
[training]
seed = ${system.seed}
gpu_allocator = ${system.gpu_allocator}
dropout = 0.1
accumulate_gradient = 1
patience = 1600
max_epochs = 0
max_steps = 20000
eval_frequency = 200
frozen_components = []
annotating_components = []
dev_corpus = "corpora.dev"
train_corpus = "corpora.train"
before_to_disk = null
[training.batcher]
@batchers = "spacy.batch_by_words.v1"
discard_oversize = false
tolerance = 0.2
get_length = null
[training.batcher.size]
@schedules = "compounding.v1"
start = 100
stop = 1000
compound = 1.001
t = 0.0
[training.logger]
@loggers = "spacy.ConsoleLogger.v1"
progress_bar = false
[training.optimizer]
@optimizers = "Adam.v1"
beta1 = 0.9
beta2 = 0.999
L2_is_weight_decay = true
L2 = 0.01
grad_clip = 1.0
use_averages = false
eps = 0.00000001
learn_rate = 0.001
[training.score_weights]
ents_f = 1.0
ents_p = 0.0
ents_r = 0.0
ents_per_type = null
[pretraining]
[initialize]
vectors = ${paths.vectors}
init_tok2vec = ${paths.init_tok2vec}
vocab_data = null
lookups = null
before_init = null
after_init = null
[initialize.components]
[initialize.tokenizer]

View file

@ -1,38 +0,0 @@
{
"lang":"de",
"name":"pipeline",
"version":"0.0.0",
"spacy_version":">=3.4.1,<3.5.0",
"description":"",
"author":"",
"email":"",
"url":"",
"license":"",
"spacy_git_version":"Unknown",
"vectors":{
"width":0,
"vectors":0,
"keys":0,
"name":null,
"mode":"default"
},
"labels":{
"ner":[
"cdtr.bic",
"cdtr.iban",
"cdtr.name",
"invoice.date",
"invoice.number",
"invoice.total"
]
},
"pipeline":[
"ner"
],
"components":[
"ner"
],
"disabled":[
]
}

View file

@ -1,13 +0,0 @@
{
"moves":null,
"update_with_oracle_cut_size":100,
"multitasks":[
],
"min_action_freq":1,
"learn_tokens":false,
"beam_width":1,
"beam_density":0.0,
"beam_update_prob":0.0,
"incorrect_spans_key":null
}

Binary file not shown.

View file

@ -1 +0,0 @@
¥movesÚÄ{"0":{},"1":{"invoice.total":-1,"invoice.number":-2,"cdtr.name":-3,"invoice.date":-4,"cdtr.iban":-5,"cdtr.bic":-6},"2":{"invoice.total":-1,"invoice.number":-2,"cdtr.name":-3,"invoice.date":-4,"cdtr.iban":-5,"cdtr.bic":-6},"3":{"invoice.total":-1,"invoice.number":-2,"cdtr.name":-3,"invoice.date":-4,"cdtr.iban":-5,"cdtr.bic":-6},"4":{"":1,"invoice.total":-1,"invoice.number":-2,"cdtr.name":-3,"invoice.date":-4,"cdtr.iban":-5,"cdtr.bic":-6},"5":{"":1}}£cfg<66>§neg_keyÀ

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
<EFBFBD>

View file

@ -1 +0,0 @@
<EFBFBD>

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
{
"mode":"default"
}

View file

@ -1,127 +0,0 @@
[paths]
train = null
dev = null
vectors = null
init_tok2vec = null
[system]
seed = 0
gpu_allocator = null
[nlp]
lang = "de"
pipeline = ["ner"]
disabled = []
before_creation = null
after_creation = null
after_pipeline_creation = null
batch_size = 1000
tokenizer = {"@tokenizers":"spacy.Tokenizer.v1"}
[components]
[components.ner]
factory = "ner"
incorrect_spans_key = null
moves = null
update_with_oracle_cut_size = 100
[components.ner.model]
@architectures = "spacy.TransitionBasedParser.v2"
state_type = "ner"
extra_state_tokens = false
hidden_width = 64
maxout_pieces = 2
use_upper = true
nO = null
[components.ner.model.tok2vec]
@architectures = "spacy.HashEmbedCNN.v2"
pretrained_vectors = null
width = 96
depth = 4
embed_size = 2000
window_size = 1
maxout_pieces = 3
subword_features = true
[corpora]
[corpora.dev]
@readers = "spacy.Corpus.v1"
path = ${paths.dev}
gold_preproc = false
max_length = 0
limit = 0
augmenter = null
[corpora.train]
@readers = "spacy.Corpus.v1"
path = ${paths.train}
gold_preproc = false
max_length = 0
limit = 0
augmenter = null
[training]
seed = ${system.seed}
gpu_allocator = ${system.gpu_allocator}
dropout = 0.1
accumulate_gradient = 1
patience = 1600
max_epochs = 0
max_steps = 20000
eval_frequency = 200
frozen_components = []
annotating_components = []
dev_corpus = "corpora.dev"
train_corpus = "corpora.train"
before_to_disk = null
[training.batcher]
@batchers = "spacy.batch_by_words.v1"
discard_oversize = false
tolerance = 0.2
get_length = null
[training.batcher.size]
@schedules = "compounding.v1"
start = 100
stop = 1000
compound = 1.001
t = 0.0
[training.logger]
@loggers = "spacy.ConsoleLogger.v1"
progress_bar = false
[training.optimizer]
@optimizers = "Adam.v1"
beta1 = 0.9
beta2 = 0.999
L2_is_weight_decay = true
L2 = 0.01
grad_clip = 1.0
use_averages = false
eps = 0.00000001
learn_rate = 0.001
[training.score_weights]
ents_f = 1.0
ents_p = 0.0
ents_r = 0.0
ents_per_type = null
[pretraining]
[initialize]
vectors = ${paths.vectors}
init_tok2vec = ${paths.init_tok2vec}
vocab_data = null
lookups = null
before_init = null
after_init = null
[initialize.components]
[initialize.tokenizer]

View file

@ -1,40 +0,0 @@
{
"lang":"de",
"name":"pipeline",
"version":"0.0.0",
"spacy_version":">=3.1.1,<3.2.0",
"description":"",
"author":"",
"email":"",
"url":"",
"license":"",
"spacy_git_version":"ffaead8fe",
"vectors":{
"width":0,
"vectors":0,
"keys":0,
"name":null
},
"labels":{
"ner":[
"cdtr.bic",
"cdtr.iban",
"cdtr.name",
"invoice.date",
"invoice.number",
"invoice.total"
]
},
"pipeline":[
"ner"
],
"components":[
"ner"
],
"disabled":[
],
"_sourced_vectors_hashes":{
}
}

View file

@ -1,13 +0,0 @@
{
"moves":null,
"update_with_oracle_cut_size":100,
"multitasks":[
],
"min_action_freq":1,
"learn_tokens":false,
"beam_width":1,
"beam_density":0.0,
"beam_update_prob":0.0,
"incorrect_spans_key":null
}

View file

@ -1 +0,0 @@
¥movesÚÄ{"0":{},"1":{"cdtr.name":-1,"cdtr.iban":-2,"cdtr.bic":-3,"invoice.total":-4,"invoice.date":-5,"invoice.number":-6},"2":{"cdtr.name":-1,"cdtr.iban":-2,"cdtr.bic":-3,"invoice.total":-4,"invoice.date":-5,"invoice.number":-6},"3":{"cdtr.name":-1,"cdtr.iban":-2,"cdtr.bic":-3,"invoice.total":-4,"invoice.date":-5,"invoice.number":-6},"4":{"":1,"cdtr.name":-1,"cdtr.iban":-2,"cdtr.bic":-3,"invoice.total":-4,"invoice.date":-5,"invoice.number":-6},"5":{"":1}}£cfg<66>§neg_keyÀ

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
<EFBFBD>

View file

@ -1 +0,0 @@
<EFBFBD>

File diff suppressed because it is too large Load diff

View file

@ -1,128 +0,0 @@
[paths]
train = null
dev = null
vectors = null
init_tok2vec = null
[system]
seed = 0
gpu_allocator = null
[nlp]
lang = "de"
pipeline = ["ner"]
disabled = []
before_creation = null
after_creation = null
after_pipeline_creation = null
batch_size = 1000
tokenizer = {"@tokenizers":"spacy.Tokenizer.v1"}
[components]
[components.ner]
factory = "ner"
incorrect_spans_key = null
moves = null
scorer = {"@scorers":"spacy.ner_scorer.v1"}
update_with_oracle_cut_size = 100
[components.ner.model]
@architectures = "spacy.TransitionBasedParser.v2"
state_type = "ner"
extra_state_tokens = false
hidden_width = 64
maxout_pieces = 2
use_upper = true
nO = null
[components.ner.model.tok2vec]
@architectures = "spacy.HashEmbedCNN.v2"
pretrained_vectors = null
width = 96
depth = 4
embed_size = 2000
window_size = 1
maxout_pieces = 3
subword_features = true
[corpora]
[corpora.dev]
@readers = "spacy.Corpus.v1"
path = ${paths.dev}
gold_preproc = false
max_length = 0
limit = 0
augmenter = null
[corpora.train]
@readers = "spacy.Corpus.v1"
path = ${paths.train}
gold_preproc = false
max_length = 0
limit = 0
augmenter = null
[training]
seed = ${system.seed}
gpu_allocator = ${system.gpu_allocator}
dropout = 0.1
accumulate_gradient = 1
patience = 1600
max_epochs = 0
max_steps = 20000
eval_frequency = 200
frozen_components = []
annotating_components = []
dev_corpus = "corpora.dev"
train_corpus = "corpora.train"
before_to_disk = null
[training.batcher]
@batchers = "spacy.batch_by_words.v1"
discard_oversize = false
tolerance = 0.2
get_length = null
[training.batcher.size]
@schedules = "compounding.v1"
start = 100
stop = 1000
compound = 1.001
t = 0.0
[training.logger]
@loggers = "spacy.ConsoleLogger.v1"
progress_bar = false
[training.optimizer]
@optimizers = "Adam.v1"
beta1 = 0.9
beta2 = 0.999
L2_is_weight_decay = true
L2 = 0.01
grad_clip = 1.0
use_averages = false
eps = 0.00000001
learn_rate = 0.001
[training.score_weights]
ents_f = 1.0
ents_p = 0.0
ents_r = 0.0
ents_per_type = null
[pretraining]
[initialize]
vectors = ${paths.vectors}
init_tok2vec = ${paths.init_tok2vec}
vocab_data = null
lookups = null
before_init = null
after_init = null
[initialize.components]
[initialize.tokenizer]

View file

@ -1,38 +0,0 @@
{
"lang":"de",
"name":"pipeline",
"version":"0.0.0",
"spacy_version":">=3.4.1,<3.5.0",
"description":"",
"author":"",
"email":"",
"url":"",
"license":"",
"spacy_git_version":"Unknown",
"vectors":{
"width":0,
"vectors":0,
"keys":0,
"name":null,
"mode":"default"
},
"labels":{
"ner":[
"cdtr.bic",
"cdtr.iban",
"cdtr.name",
"invoice.date",
"invoice.number",
"invoice.total"
]
},
"pipeline":[
"ner"
],
"components":[
"ner"
],
"disabled":[
]
}

View file

@ -1,13 +0,0 @@
{
"moves":null,
"update_with_oracle_cut_size":100,
"multitasks":[
],
"min_action_freq":1,
"learn_tokens":false,
"beam_width":1,
"beam_density":0.0,
"beam_update_prob":0.0,
"incorrect_spans_key":null
}

Binary file not shown.

View file

@ -1 +0,0 @@
¥movesÚÄ{"0":{},"1":{"invoice.total":-1,"invoice.number":-2,"invoice.date":-3,"cdtr.name":-4,"cdtr.iban":-5,"cdtr.bic":-6},"2":{"invoice.total":-1,"invoice.number":-2,"invoice.date":-3,"cdtr.name":-4,"cdtr.iban":-5,"cdtr.bic":-6},"3":{"invoice.total":-1,"invoice.number":-2,"invoice.date":-3,"cdtr.name":-4,"cdtr.iban":-5,"cdtr.bic":-6},"4":{"":1,"invoice.total":-1,"invoice.number":-2,"invoice.date":-3,"cdtr.name":-4,"cdtr.iban":-5,"cdtr.bic":-6},"5":{"":1}}£cfg<66>§neg_keyÀ

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
<EFBFBD>

View file

@ -1 +0,0 @@
<EFBFBD>

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
{
"mode":"default"
}

View file

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Workflow Instance -->
<item name="workflow.endpoint"><value xsi:type="xs:string">https://alexander-logistics.office-workflow.de/api/</value></item>
<item name="workflow.userid"><value xsi:type="xs:string">admin</value></item>
<item name="workflow.password"><value xsi:type="xs:string">imixs4.null</value></item>
<!-- -->
<item name="workflow.query"><value xsi:type="xs:string">($workflowgroup:"Rechnungseingang" OR $workflowgroup:"Sachrechnung") AND ($taskid:5900)</value></item>
<item name="workflow.pagesize"><value xsi:type="xs:int">100</value></item>
<item name="workflow.pageindex"><value xsi:type="xs:int">30</value></item>
<item name="workflow.entities">
<value xsi:type="xs:string">cdtr.name</value>
<value xsi:type="xs:string">cdtr.iban</value>
<value xsi:type="xs:string">cdtr.bic</value>
<value xsi:type="xs:string">invoice.total</value>
<value xsi:type="xs:string">invoice.date</value>
<value xsi:type="xs:string">invoice.number</value>
</item>
<item name="workflow.locale">
<value xsi:type="xs:string">en_GB</value>
<value xsi:type="xs:string">en_US</value>
<value xsi:type="xs:string">de_DE</value>
</item>
<!-- Tika OCR Server -->
<item name="tika.ocrmode"><value xsi:type="xs:string">OCR_ONLY</value></item>
<item name="tika.options">
<value xsi:type="xs:string">X-Tika-OCRLanguage=eng+deu</value>
<value xsi:type="xs:string">X-Tika-PDFocrStrategy=OCR_ONLY</value>
</item>
<!-- ML spaCy Server -->
<item name="ml.validation.endpoint"><value xsi:type="xs:string">http://imixs-ml-spacy:8000/</value></item>
<item name="ml.validation.model"><value xsi:type="xs:string">invoice-de-0.1.0</value></item>
<item name="ml.validation.filepattern"><value xsi:type="xs:string">.pdf|.PDF</value></item>
</document>

View file

@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Workflow Instance -->
<item name="workflow.endpoint"><value xsi:type="xs:string">https://alexander-logistics.office-workflow.de/api/</value></item>
<item name="workflow.userid"><value xsi:type="xs:string">admin</value></item>
<item name="workflow.password"><value xsi:type="xs:string">imixs4.null</value></item>
<item name="workflow.entities">
<value xsi:type="xs:string">cdtr.name</value>
<value xsi:type="xs:string">cdtr.iban</value>
<value xsi:type="xs:string">cdtr.bic</value>
<value xsi:type="xs:string">invoice.total</value>
<value xsi:type="xs:string">invoice.date</value>
<value xsi:type="xs:string">invoice.number</value>
</item>
<item name="workflow.locale">
<value xsi:type="xs:string">en_GB</value>
<value xsi:type="xs:string">en_US</value>
<value xsi:type="xs:string">de_DE</value>
</item>
<!-- Tika OCR Server -->
<item name="tika.ocrmode"><value xsi:type="xs:string">OCR_ONLY</value></item>
<item name="tika.options">
<value xsi:type="xs:string">X-Tika-OCRLanguage=eng+deu</value>
<value xsi:type="xs:string">X-Tika-PDFocrStrategy=OCR_ONLY</value>
</item>
<!-- ML spaCy Server -->
<item name="ml.training.endpoint"><value xsi:type="xs:string">http://imixs-ml-spacy:8000/</value></item>
<item name="ml.training.model"><value xsi:type="xs:string">invoice-de-0.2.0</value></item>
<item name="ml.training.filepattern"><value xsi:type="xs:string">.pdf|.PDF</value></item>
<!-- LOW | GOOD -->
<item name="ml.training.quality"><value xsi:type="xs:string">LOW</value></item>
<!-- Define the training set and taining mode -->
<item name="workflow.query"><value xsi:type="xs:string">($workflowgroup:"Rechnungseingang" OR $workflowgroup:"Sachrechnung") AND ($taskid:5900)</value></item>
<item name="workflow.pagesize"><value xsi:type="xs:int">1000</value></item>
<item name="workflow.pageindex"><value xsi:type="xs:int">0</value></item>
<item name="ml.training.iterations"><value xsi:type="xs:string">5</value></item>
<item name="ml.training.dropoutrate"><value xsi:type="xs:string">0.0</value></item>
<item name="ml.options">
<value xsi:type="xs:string">min_losses=0.0&amp;retrain_rate=100</value>
</item>
</document>

View file

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Workflow Instance -->
<item name="workflow.endpoint"><value xsi:type="xs:string">https://alexander-logistics.office-workflow.de/api/</value></item>
<item name="workflow.userid"><value xsi:type="xs:string">admin</value></item>
<item name="workflow.password"><value xsi:type="xs:string">imixs4.null</value></item>
<item name="workflow.entities">
<value xsi:type="xs:string">cdtr.name</value>
<value xsi:type="xs:string">cdtr.iban</value>
<value xsi:type="xs:string">cdtr.bic</value>
<value xsi:type="xs:string">invoice.total</value>
<value xsi:type="xs:string">invoice.date</value>
<value xsi:type="xs:string">invoice.number</value>
</item>
<item name="workflow.locale">
<value xsi:type="xs:string">en_GB</value>
<value xsi:type="xs:string">en_US</value>
<value xsi:type="xs:string">de_DE</value>
</item>
<!-- Tika OCR Server -->
<item name="tika.ocrmode"><value xsi:type="xs:string">OCR_ONLY</value></item>
<item name="tika.options">
<value xsi:type="xs:string">X-Tika-OCRLanguage=eng+deu</value>
<value xsi:type="xs:string">X-Tika-PDFocrStrategy=OCR_ONLY</value>
</item>
<!-- ML spaCy Server -->
<item name="ml.training.endpoint"><value xsi:type="xs:string">http://imixs-ml-spacy:8000/</value></item>
<item name="ml.training.model"><value xsi:type="xs:string">invoice-de-0.2.0</value></item>
<item name="ml.training.filepattern"><value xsi:type="xs:string">.pdf|.PDF</value></item>
<!-- LOW | GOOD -->
<item name="ml.training.quality"><value xsi:type="xs:string">LOW</value></item>
<!-- Define the training set and taining mode -->
<item name="workflow.query"><value xsi:type="xs:string">($workflowgroup:"Rechnungseingang" OR $workflowgroup:"Sachrechnung") AND ($taskid:5900)</value></item>
<item name="workflow.pagesize"><value xsi:type="xs:int">100</value></item>
<item name="workflow.pageindex"><value xsi:type="xs:int">40</value></item>
</document>

View file

@ -1 +0,0 @@
/target/

View file

@ -1,430 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>office-alexander-logistics</artifactId>
<groupId>com.alexander-logistics</groupId>
<version>1.3.5</version>
</parent>
<artifactId>office-alexander-logistics-app</artifactId>
<packaging>war</packaging>
<name>Imixs Office Workflow App</name>
<profiles>
<profile>
<id>docker</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<exec executable="docker">
<arg value="build" />
<arg value="-t" />
<arg value="imixs/${imixs-office.applicationname}" />
<arg value="../." />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>debug</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<exec executable="docker">
<arg value="build" />
<arg value="-f" />
<arg value="../Dockerfile-wildfly-debug" />
<arg value="-t" />
<arg value="imixs/${imixs-office.applicationname}" />
<arg value="../." />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>kubernetes</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<exec executable="docker">
<arg value="build" />
<arg value="-t" />
<arg
value="imixs/${imixs-office.applicationname}:${project.version}" />
<arg value="../." />
</exec>
<exec executable="docker">
<arg value="tag" />
<arg
value="imixs/${imixs-office.applicationname}:${project.version}" />
<arg
value="${org.imixs.kubernetes.registry}/imixs/${imixs-office.applicationname}:${project.version}" />
</exec>
<exec executable="docker">
<arg value="push" />
<arg
value="${org.imixs.kubernetes.registry}/imixs/${imixs-office.applicationname}:${project.version}" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<testResources>
<testResource>
<directory>${basedir}/../reports</directory>
</testResource>
<testResource>
<directory>${basedir}/../workflow</directory>
</testResource>
<testResource>
<directory>${basedir}/src/test/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<filtering>true</filtering>
<!-- this is relative to the pom.xml directory -->
<directory>${custom.webResources}</directory>
<includes>
<include>**/WEB-INF/*</include>
<!-- include any other file types you want to filter -->
</includes>
</resource>
</webResources>
<workDirectory>target/overlay-war-folder</workDirectory>
<!-- We exclude libs form the parent WAR artifact -->
<overlays>
<overlay>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-app</artifactId>
<excludes>
<exclude>WEB-INF/lib/*.jar</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
<plugin>
<groupId>org.imixs.maven</groupId>
<artifactId>manik-hotdeploy-maven-plugin</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- List Source and Target folders for Autodeploy and Hotdeploy -->
<autodeployments>
<deployment>
<!-- wildcard deployment -->
<source>target/*.{war,ear,jar}</source>
<target>../docker/deployments/</target>
<unpack>true</unpack>
</deployment>
</autodeployments>
<hotdeployments>
<deployment>
<source>src/main/webapp</source>
<target>../docker/deployments/office-alexander-logistics.war</target>
</deployment>
</hotdeployments>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Imixs Workflow -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-core</artifactId>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-engine</artifactId>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-jax-rs</artifactId>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-faces</artifactId>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-index-lucene</artifactId>
<scope>compile</scope>
</dependency>
<!-- Marty -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-marty</artifactId>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Imixs-Office-Workflow -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-app</artifactId>
<type>war</type>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-util</artifactId>
<scope>compile</scope>
</dependency>
<!-- Imixs-Archive -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-archive-api</artifactId>
<scope>compile</scope>
</dependency>
<!-- Imixs Data -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-groups</artifactId>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-views</artifactId>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-documents</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-importer</artifactId>
<scope>compile</scope>
</dependency>
<!-- SEPA Adapter -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-sepa</artifactId>
<scope>compile</scope>
</dependency>
<!-- DATEV Adapter -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-datev</artifactId>
<scope>compile</scope>
</dependency>
<!-- QR Code -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-qrcode</artifactId>
<scope>compile</scope>
</dependency>
<!-- POI Adapter -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-poi</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-ai-workflow</artifactId>
<version>${org.imixs.ai.version}</version>
<scope>compile</scope>
</dependency>
<!-- E-Invoice -->
<dependency>
<groupId>org.imixs.util</groupId>
<artifactId>imixs-e-invoice</artifactId>
<version>${org.imixs.e-invoice.version}</version>
</dependency>
<!-- xsl 2.0 support for Reporting / Chart Diagrams -->
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
</dependency>
<!-- Apache PDFBox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>${apache.pdfbox.version}</version>
<scope>compile</scope>
</dependency>
<!-- Apache Commons FTP Client -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<!-- Microsoft oauth token -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
<scope>test</scope>
</dependency>
<!-- JUnit Tests
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
-->
<!-- JAX-RS 2.0 Test dependencies -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.3.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<!-- KSeF 2.0 Client
<dependency>
<groupId>pl.akmf.ksef-sdk</groupId>
<artifactId>ksef-client</artifactId>
<version>3.0.4</version>
<scope>test</scope>
</dependency>
-->
</dependencies>
<!--
<repositories>
<repository>
<id>github-cirfmf</id>
<url>https://maven.pkg.github.com/CIRFMF/ksef-client-java</url>
</repository>
</repositories>
-->
</project>

View file

@ -1,600 +0,0 @@
package com.alexanderlogistics.einvoice;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.imixs.archive.core.SnapshotService;
import org.imixs.einvoice.EInvoiceFormatException;
import org.imixs.einvoice.EInvoiceModel;
import org.imixs.einvoice.EInvoiceModelFactory;
import org.imixs.einvoice.EInvoiceModelKSeF;
import org.imixs.einvoice.EInvoiceNS;
import org.imixs.einvoice.TradeLineItem;
import org.imixs.einvoice.TradeParty;
import org.imixs.workflow.FileData;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.SignalAdapter;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.engine.WorkflowService;
import org.imixs.workflow.exceptions.AdapterException;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
import org.imixs.workflow.util.XMLParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.alexanderlogistics.BusinessPartnerService;
import com.alexanderlogistics.InvoiceService;
import com.alexanderlogistics.InvoiceUtil;
import com.alexanderlogistics.xml.CargosoftXMLInvoiceImportService;
import jakarta.inject.Inject;
/**
* The KSeFAdapter converts a Cargsoft outbound invoice into an KSeF XML
* e-invoice and sends the xml file to the polish KSeF API
*
* The adapter can be configured by the model:
*
* <pre>
* {@code
<ksef name="create">
<textblock>textblock-ref</textblock>
<template>filename</template>
<debug>true</debug>
</ksef>
}
* </pre>
*
* <p>
* NIP: The adapter needs the NIP (vat-id). If we do not find the partner.vat in
* the business object, we do a lookup on the D-Cargosoft object and try the vat
* id from there. This is because the partner.vat is a field which was not
* defined before.
*
* <p>
* Wenn Debug = true gibt der Adapter alle einzelschritte auf der console aus
* und erzeugt zusätzlich die factur-x xml und txt dateien.
*
*
*
* @version 1.0
* @author rsoika
*/
public class KSeFAdapterDeprecated implements SignalAdapter {
final String TYPE_TEXTBLOCK = "textblock";
public static final String DOCUMENT_ERROR = "DOCUMENT_ERROR";
public static final String CONFIG_ERROR = "CONFIG_ERROR";
public static final String API_ERROR = "API_ERROR";
public static final String BUSINESSPARTNER_ERROR = "BUSINESSPARTNER_ERROR";
public static final String LINE_ITEMS_PROPERTY = "invoice.items";
private static Logger logger = Logger.getLogger(EInvoiceAdapter.class.getName());
public static SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN);
public static NumberFormat numberFormat = NumberFormat.getInstance(Locale.GERMANY);
boolean debug = false;
@Inject
WorkflowService workflowService;
@Inject
DocumentService documentService;
@Inject
SnapshotService snapshotService;
@Inject
BusinessPartnerService businessPartnerService;
@Inject
InvoiceService invoiceService;
/**
* This method
*
* @throws PluginException
*/
@Override
public ItemCollection execute(ItemCollection workitem, ItemCollection event)
throws AdapterException, PluginException {
logger.info("├── 🔜 Convert Invoice to KSeF...");
// read configuration....
ItemCollection eInvoiceConfig = workflowService.evalWorkflowResult(event, "ksef",
workitem,
false);
if (eInvoiceConfig == null || !eInvoiceConfig.hasItem("CREATE")) {
throw new PluginException(EInvoiceAdapter.class.getSimpleName(), CONFIG_ERROR,
"missing e-invoice/ksef configuration in model event - please check model configuration");
}
ItemCollection ksefCreateDefinition = XMLParser.parseItemStructure(eInvoiceConfig.getItemValueString("CREATE"));
try {
// Load the e-invoice template....
FileData xmlFileData = loadXMLTemplate(workitem, ksefCreateDefinition);
updateEInvoice(xmlFileData, workitem);
// append XML document
logger.info("│ ├── attach KSeF e-invoice...");
workitem.addFileData(xmlFileData);
} catch (PluginException e) {
throw new AdapterException(e);
}
return workitem;
}
/**
* This method updates an e-invoice template with the data stored in the
* workitem.
*
* First the method loads an EInvoiceModel based on the provided XML Template
* and than updates the e-invoice data based on the items stored in the given
* workitem.
*
* @param workitem
* @throws PluginException
*/
public void updateEInvoice(FileData fileDataXMLTemplate, ItemCollection workitem) throws PluginException {
try {
EInvoiceModel model = EInvoiceModelFactory.read(new ByteArrayInputStream(fileDataXMLTemplate.getContent()));
model.setId(workitem.getItemValueString("invoice.number"));
// date
model.setIssueDateTime(workitem.getItemValueLocalDate("invoice.date"));
// Set Performance Date
if (workitem.getItemValueDate("invoice.performancedate") == null) {
// hilfs code um das invoice.performancedate nachträglich zu parsen
syncPerformanceDate(workitem);
}
((EInvoiceModelKSeF) model)
.setPerformanceDateTime(workitem.getItemValueLocalDate("invoice.performancedate"));
// Update Addresses
TradeParty billingAddress = buildAddress(workitem, "buyer", model);
model.setTradeParty(billingAddress);
// set Tax Type based on vatID - as a result taxType is 1=Poland 2=EU 3=Other
((EInvoiceModelKSeF) model).setTaxType(workitem.getItemValueString("partner.vat"));
workitem.setItemValue("invoice.tax.type", ((EInvoiceModelKSeF) model).getTaxType());
// Update Invoice Type (RodzajFaktury) -> VAT | KOR
Element elementFa = model.findOrCreateChildNode(model.getRoot(), EInvoiceNS.KSEF, "Fa");
if (isKorrekturRechnung(workitem)) {
((EInvoiceModelKSeF) model).setRodzajFaktury("KOR");
logger.info("│ ├── invoice type=KOR");
// Set correction data (DaneFaKorygowanej) - required for KOR invoices
Element daneFaKorygowanej = model.findOrCreateChildNodeAfter(
elementFa, EInvoiceNS.KSEF, "DaneFaKorygowanej", "RodzajFaktury");
Date correctionInvoiceDate = workitem.getItemValueDate("invoice.date");
// try to lookup original invoice by invoice.CorrectionInvoiceNumber
ItemCollection correctionInvoice = invoiceService
.findOutboundInvoiceByNumber(workitem.getItemValueString("invoice.CorrectionInvoiceNumber"));
if (correctionInvoice != null) {
correctionInvoiceDate = correctionInvoice.getItemValueDate("invoice.date");
logger.info("│ ├── found original invoice, date: " + correctionInvoiceDate);
} else {
logger.info("│ ├── ⚠️ original invoice not found, using current date as fallback");
}
// Original invoice date (DataWystFaKorygowanej) - required
if (correctionInvoiceDate != null) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String sCorrectionDate = formatter.format(correctionInvoiceDate);
model.updateElementValue(daneFaKorygowanej, EInvoiceNS.KSEF,
"DataWystFaKorygowanej", sCorrectionDate);
}
// Original invoice number (NrFaKorygowanej) - required
model.updateElementValue(daneFaKorygowanej, EInvoiceNS.KSEF,
"NrFaKorygowanej", workitem.getItemValueString("invoice.CorrectionInvoiceNumber"));
// NrKSeFN = 1 means the original invoice was issued outside KSeF
model.updateElementValue(daneFaKorygowanej, EInvoiceNS.KSEF, "NrKSeFN", "1");
} else {
// normale rechnung
((EInvoiceModelKSeF) model).setRodzajFaktury("VAT");
logger.info("│ ├── invoice type=VAT");
}
// set currency
model.updateElementValue(elementFa, EInvoiceNS.KSEF, "KodWaluty",
workitem.getItemValueString("invoice.currency"));
// Update Invoice Items
// Here we compute the pos number independent if the _childitems hold a posnum.
// This is because a new imported cargosoft invoice does not provide numPos
// items in the child list. So it is important to generate the pos numbers here
// one by one
List<ItemCollection> invoiceItems = InvoiceUtil.explodeChildList(workitem, "_childitems");
double lineTotalAmount = 0.00;
int pos = 1;
for (ItemCollection invoiceItem : invoiceItems) {
TradeLineItem tradeLineItem = buildTradeLineItem(invoiceItem, pos);
model.setTradeLineItem(tradeLineItem);
lineTotalAmount = lineTotalAmount + tradeLineItem.getTotal();
pos++;
}
// Summenbildung
/*
* Field mapping:
* <ul>
* <li>taxType "1" (Poland): P_13_1 (domestic VAT)</li>
* <li>taxType "2" (EU): P_13_6_2 (intra-community delivery, 0%)</li>
* <li>taxType "3" (Non-EU): P_13_6_3 (export, 0%)</li>
* </ul>
*/
model.setNetTotalAmount(workitem.getItemValueDouble("invoice.total.net"));
// ?? has no function
model.setTaxRate(workitem.getItemValueDouble("invoice.total.tax"));
// Tax
/*
* P_14_1
*
* This call also generate P_14_1W bei fremdwährung
*/
model.setTaxTotalAmount(InvoiceUtil.round(workitem.getItemValueDouble("invoice.total")
- workitem.getItemValueDouble("invoice.total.net")));
/*
* If we have Foreign Currency we need to set P_14_1W in case we are tax type 1
*/
if (!"PLN".equals(workitem.getItemValueString("invoice.currency"))) {
if ("1".equals(((EInvoiceModelKSeF) model).getTaxType())) {
// compute rate
double rate = workitem.getItemValueDouble("invoice.rate");
logger.info("│ ├── rate=" + rate);
double totalTax = InvoiceUtil.round(workitem.getItemValueDouble("invoice.total.tax"));
logger.info("│ ├── total.tax=" + totalTax);
BigDecimal value = BigDecimal.valueOf(totalTax)
.divide(BigDecimal.valueOf(rate), 10, RoundingMode.HALF_UP);
// P_14_1W must come directly after P_14_1
logger.info("│ ├── P_14_1W=" + value);
Element element = model.findOrCreateChildNodeAfter(elementFa, EInvoiceNS.KSEF, "P_14_1W", "P_14_1");
element.setTextContent(value.setScale(2, RoundingMode.HALF_UP).toPlainString());
}
}
// Brutto
/*
* P_15
*/
model.setGrandTotalAmount(workitem.getItemValueDouble("invoice.total"));
/*
* KursWalutyZ
*
* Für Rechnungen in Fremdwährung obligatorisch. Anzuwenden ist der NBP-
* Durchschnittskurs des Tages vor Entstehen der Steuerpflicht (Art. 31a
* UStG-PL).
* Dezimalformat mit Punkt.
*/
String currency = workitem.getItemValueString("invoice.currency");
if (!currency.isBlank() && !"PLN".equals(currency)) {
Element p15 = model.findChildNode(elementFa, EInvoiceNS.KSEF, "P_15");
if (p15 != null) {
Double rate = workitem.getItemValueDouble("invoice.rate");
logger.info("│ ├── set KursWalutyZ = " + rate);
Element element = model.findOrCreateChildNodeAfter(elementFa, EInvoiceNS.KSEF, "KursWalutyZ",
"P_15");
element.setTextContent(rate.toString());
}
}
// finally set the due date at the end of the XML tree
model.setDueDateTime(workitem.getItemValueLocalDate("invoice.duedate"));
/*
* finally update the template file
*/
fileDataXMLTemplate.setContent(model.getContent());
} catch (FileNotFoundException | EInvoiceFormatException | TransformerException e) {
throw new PluginException(this.getClass().getName(), DOCUMENT_ERROR, e.getMessage(), e);
}
}
/**
* Dies ist eine Hilfsmethode die nachträglich das invoice.performancedate aus
* dem Cargosoft XML ausliest
*
* @param workitem
* @throws PluginException
*/
private void syncPerformanceDate(ItemCollection workitem) throws PluginException {
if (!workitem.hasItem("invoice.performancedate")) {
try {
logger.info("----Resync cargosoft performancedate....");
DocumentBuilder documentBuilder;
// hole die XML Datei
FileData cargoXML = snapshotService.getWorkItemFile(workitem.getUniqueID(),
workitem.getItemValueString("cargosoft.import.filename"));
if (cargoXML != null) {
InputStream inputStream = new ByteArrayInputStream(cargoXML.getContent());
InputSource inputSource = new InputSource(inputStream);
documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = documentBuilder.parse(inputSource);
// Performance Date
CargosoftXMLInvoiceImportService.readXMLValue(doc,
"/Invoices/Invoice/InvoiceHeader/PerformanceDate",
workitem, "invoice.performancedate",
Date.class);
// falls keines gefunden wurde nehmen wir das invoice date
if (workitem.getItemValueDate("invoice.performancedate") == null) {
workitem.setItemValue("invoice.performancedate", workitem.getItemValueDate("invoice.date"));
}
}
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "XML_ERROR",
e.getMessage());
}
}
}
/**
* Gibt True zurück wenn es eine korrektur rechnung ist
*
* InvoiceHeader/Correction=true
* InvoiceHeader/CorrectionInvoiceNumber !empty
*
*
* @param workitem
* @return
*/
private boolean isKorrekturRechnung(ItemCollection workitem) {
return ("true".equals(workitem.getItemValueString("invoice.correction"))
&& !workitem.getItemValueString("invoice.CorrectionInvoiceNumber").isEmpty());
}
/**
* Erstellt ein TradeParty Objekt aus einer Liste von Adresszeilen.
*
* @param addressLines Liste der Adresszeilen
* @param type Der Typ der TradeParty
* @return TradeParty
*/
public TradeParty buildAddress(ItemCollection workitem, String type, EInvoiceModel model) throws PluginException {
String partnerID = workitem.getItemValueString("partner.id");
if (partnerID == null || partnerID.isEmpty()) {
throw new PluginException(this.getClass().getName(), DOCUMENT_ERROR, "Missing partnerID");
}
ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(partnerID);
if (businessPartner == null) {
throw new PluginException(this.getClass().getName(), DOCUMENT_ERROR,
"Business Partner ID '" + partnerID + "' does not exist");
}
/**
* Migration:
* If the business partner does not yet have the item "partner.vat" we try here
* to resync this information from the cargosoftkreditor object. This is needed
* because the partner.vat was not initially defined by the synch processor and
* so many partner objects do not yet provide this information.
*/
if (businessPartner.getItemValueString("partner.vat").isEmpty()) {
logger.info("│ ├── BusinessPartner " + partnerID + " does not provide vat-id - try to migrate....");
String dNumber = businessPartner.getItemValueString("dbtr.number");
if (!dNumber.isEmpty()) {
try {
String query = "(type:cargosoftkreditor) AND (name:" + dNumber + ")";
List<ItemCollection> result;
result = documentService.find(query, 1, 0);
if (result != null && result.size() > 0) {
ItemCollection creditorData = result.get(0);
String vatID = creditorData.getItemValueString("_vendor_vat_registration_id");
logger.info("│ ├── synchronize VAT Registrytion ID: " + vatID);
// update business partner
businessPartner.setItemValue("partner.vat", vatID);
documentService.saveByNewTransaction(businessPartner);
}
} catch (Exception e) {
// should not happen!
logger.info("│ ├── ⚠️ Failed to sync BusinessPartner : " + e.getMessage());
}
}
}
TradeParty tradeParty = new TradeParty(type);
// Name ist immer die erste Zeile
tradeParty.setName(businessPartner.getItemValueString("partner.name"));
tradeParty.setCountryId(businessPartner.getItemValueString("partner.country"));
tradeParty.setCityName(businessPartner.getItemValueString("partner.city"));
tradeParty.setPostcodeCode(businessPartner.getItemValueString("partner.zip"));
tradeParty.setStreetAddress(businessPartner.getItemValueString("partner.address"));
if ("buyer".equals(type)) {
// if we do NOT have a partner.vat we can not upload the invoice!
String partnerVAT = businessPartner.getItemValueString("partner.vat");
if (partnerVAT.isBlank()) {
// Just a warning
logger.warning("│ ├── ⚠️ Business Partner ID '" + partnerID + "' does not contain a VAT ID !");
// throw new PluginException(this.getClass().getName(), BUSINESSPARTNER_ERROR,
// "Business Partner ID '" + partnerID + "' does not contain a VAT ID !");
}
workitem.setItemValue("partner.vat", partnerVAT);
tradeParty.setVatNumber(partnerVAT);
// Update or create NrKlienta element directly under Podmiot2
Element podmiot2 = model.findOrCreateChildNode(model.getRoot(), EInvoiceNS.KSEF, "Podmiot2");
model.updateElementValue(podmiot2, EInvoiceNS.KSEF, "NrKlienta",
businessPartner.getItemValueString("dbtr.number"));
}
return tradeParty;
}
/**
* Parses the data list of an invoice line and returns a TradeLineItem object.
* The order of the list items must be exactly!
*
* # 16.04.2026
* Laut Herrn Grzegorz Grzelczyk dürfen in den Rechnungspositionen nur netto
* werte eingetragen sein. Siehe buildTradeLineItem()
*
* Des weiteren soll anstatt datev.text (pos nummer) der original billing text
* ausgewiesen werden
*/
private TradeLineItem buildTradeLineItem(ItemCollection orderItem, int pos) {
if (orderItem == null) {
return null;
}
// TradeLineItem tradeLineItem = new
// TradeLineItem(orderItem.getItemValueString("numpos"));
// We do not trust the item 'numPos' here because it can be empty for new
// invoices!
TradeLineItem tradeLineItem = new TradeLineItem(pos + "");
// Herrn Grzegorz Grzelczyk möchte hier BillingText
// tradeLineItem.setName(orderItem.getItemValueString("datev.text"));
// tradeLineItem.setName(orderItem.getItemValueString("billingtext"));
// Herr Grzelczyk will das alle billing texte aus der liste, verkettet
// ausgegeben werden.
List<String> billingTexts = orderItem.getItemValue("billingtext");
String billingTextName = billingTexts == null
? ""
: String.join(", ", billingTexts);
final int MAX_LENGTH = 512;
if (billingTextName.length() > MAX_LENGTH) {
billingTextName = billingTextName.substring(0, MAX_LENGTH);
}
tradeLineItem.setName(billingTextName);
tradeLineItem.setQuantity(1);
double vat = orderItem.getItemValueDouble("datev.vatrate"); // 23.00
double netto = orderItem.getItemValueDouble("datev.umsatz"); // 970.00
// # 16.04.2026
// Der total bezieht sich laut Herrn Grzegorz Grzelczyk ausschließlich auf den
// Nettowert x Menge.
// Der Brutto Wert ist hier falsch! Da die Menge immer 1 ist ist das beide male
// der selbe wert
// WRONG: tradeLineItem.setTotal(brutto);
// double brutto = netto * (1 + (vat / 100));
// double steuer = brutto - netto;
tradeLineItem.setTaxRate(vat);
tradeLineItem.setNetPrice(netto);
tradeLineItem.setTotal(netto); // menge x netto
return tradeLineItem;
}
/**
* This method loads a text-block for a specified ref and appends the named
* fileData object of this document.
*
* @param document
* @throws PluginException
*/
private FileData loadXMLTemplate(ItemCollection workitem, ItemCollection config)
throws PluginException {
String textblock = config.getItemValueString("textblock");
String template = config.getItemValueString("template");
String sourceName = config.getItemValueString("source");
try {
debug = Boolean.parseBoolean(config.getItemValueString("debug"));
} catch (Exception e) {
}
String targetName = "ksef.xml";
// adapt text....
sourceName = workflowService.adaptText(sourceName, workitem);
if ((template == null || template.isEmpty()) || (textblock == null || textblock.isEmpty())) {
throw new PluginException(EInvoiceAdapter.class.getSimpleName(),
CONFIG_ERROR,
"invalid e-invoice configuration in model event - textblock/template reference not defined!");
}
// load the text block
FileData fileData = loadTextBlockFileData(textblock, template);
// do we found the document?
if (fileData == null) {
throw new PluginException(EInvoiceAdapter.class.getSimpleName(),
CONFIG_ERROR,
"invalid e-invoice configuration in model event - textblock/template: " + textblock + "/" + template
+ " not found!");
}
fileData.setName(targetName);
return fileData;
}
/**
* This method returns a text-block ItemCollection for a specified name.
*
* @param name in attribute txtname
*
*
*/
public FileData loadTextBlockFileData(String name, String fileName) {
ItemCollection textBlockItemCollection = null;
// load text-block by name....
String sQuery = "(type:\"" + TYPE_TEXTBLOCK + "\" AND txtname:\"" + name + "\")";
Collection<ItemCollection> col;
try {
// find the textblock...
col = documentService.find(sQuery, 1, 0);
if (col.size() > 0) {
textBlockItemCollection = col.iterator().next();
// fetch the fileData...
return snapshotService.getWorkItemFile(textBlockItemCollection.getUniqueID(), fileName);
} else {
logger.warning("Missing text-block : '" + name + "'");
}
} catch (QueryException e) {
logger.warning("getTextBlock - invalid query: " + e.getMessage());
}
return null;
}
}

View file

@ -1,181 +0,0 @@
package org.imixs.workflow.office.forms;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.faces.data.WorkflowController;
import jakarta.enterprise.context.ConversationScoped;
import jakarta.enterprise.event.Event;
import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
* The AnalyticController is a conversationScoped controller that provides
* values for the analytic-custom parts.
* <p>
* A custom implementation can react on AnalyticEvent to compute values and
* datasets.
* <p>
* The controller implements a caching mechanism to avoid repeated calls for new
* analytic values. If the analytic value is already stored in the current
* workitem, no new value will be fired.
*
*
* @author rsoika
*
*/
@Named
@ConversationScoped
public class AnalyticController implements Serializable {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
@Inject
protected Event<AnalyticEvent> analyticEvents;
@Inject
protected WorkflowController workflowController;
/**
* Returns a analytic value as a String for a given key.
*
* @param key
* @return
*/
public String getAsString(String key) {
ItemCollection analyticData = computeValue(key);
return analyticData.getItemValueString("value");
}
/**
* Returns a analytic value as a Json String for a given key.
*
* @param key
* @return
*/
public String getAsJson(String key) {
ItemCollection analyticData = computeValue(key);
String jsonval = analyticData.getItemValueString("value");
if (jsonval == null || jsonval.isEmpty()) {
return "null";
} else {
return jsonval;
}
}
/**
* Returns a analytic value as a Double for a given key.
*
* @param key
* @return
*/
public double getAsDouble(String key) {
ItemCollection analyticData = computeValue(key);
return analyticData.getItemValueDouble("value");
}
/**
* Returns the analytic label for a given key
*
* @param key
* @return
*/
public String getLabel(String key) {
ItemCollection analyticData = computeValue(key);
return analyticData.getItemValueString("label");
}
/**
* Returns the analytic optional link for a given key
*
* @param key
* @return
*/
public String getLink(String key) {
ItemCollection analyticData = computeValue(key);
return analyticData.getItemValueString("link");
}
/**
* Returns the analytic description for a given key
*
* @param key
* @return
*/
public String getDescription(String key) {
ItemCollection analyticData = computeValue(key);
return analyticData.getItemValueString("description");
}
/**
* Computes an analytic value. The method cache the value in the item key.
*
* An observer controller is responsible to cache or reset the cached values if
* needed.
*
* @param key
* @return
*/
protected ItemCollection computeValue(String key) {
if (workflowController.getWorkitem() != null) {
logger.fine("fire analytic event for key '" + key + "'");
// Fire the Analytics Event for this key
AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
if (analyticEvents != null) {
analyticEvents.fire(event);
if (event.getValue() != null) {
ItemCollection details = new ItemCollection();
details.setItemValue("value", event.getValue());
details.setItemValue("label", event.getLabel());
details.setItemValue("description", event.getDescription());
details.setItemValue("link", event.getLink());
// cache result
implodeDetails(key, details);
}
}
}
// analytic value is now already cached!
return explodeDetails(key);
}
/**
* Convert the List of ItemCollections back into a List of Map elements
*
* @param workitem
*/
@SuppressWarnings({ "rawtypes" })
private void implodeDetails(String key, ItemCollection details) {
// convert the child ItemCollection elements into a List of Map
List<Map> detailsList = new ArrayList<Map>();
detailsList.add(details.getAllItems());
workflowController.getWorkitem().replaceItemValue(key, detailsList);
}
/**
* converts the Map List of a workitem into a List of ItemCollectons
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private ItemCollection explodeDetails(String key) {
// convert current list of childItems into ItemCollection elements
List<Object> mapOrderItems = workflowController.getWorkitem().getItemValue(key);
if (mapOrderItems != null && mapOrderItems.size() > 0) {
ItemCollection itemCol = new ItemCollection((Map) mapOrderItems.get(0));
return itemCol;
}
// return empty collection
ItemCollection dummy = new ItemCollection();
dummy.setItemValue("value", "");
dummy.setItemValue("label", "");
dummy.setItemValue("description", "No data available");
return dummy;
}
}

View file

@ -1,66 +0,0 @@
package org.imixs.workflow.office.forms;
import org.imixs.workflow.ItemCollection;
/**
* An AnalyticEvent is send by the AnalyticController during initialization
*/
public class AnalyticEvent {
private String key;
private Object value = null;
private String label = "";
private String description = "";
private String link = "";
private ItemCollection workitem = null;
public AnalyticEvent(String key, ItemCollection workitem) {
this.key = key;
this.workitem = workitem;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public ItemCollection getWorkitem() {
return workitem;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View file

@ -1,172 +0,0 @@
/*******************************************************************************
* Imixs Workflow Technology
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
* http://www.imixs.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
*
*******************************************************************************/
package org.imixs.workflow.office.forms;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.imixs.workflow.dataview.DataViewService;
import org.imixs.workflow.exceptions.QueryException;
import org.imixs.workflow.faces.data.WorkflowController;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.Conversation;
import jakarta.enterprise.context.ConversationScoped;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.servlet.http.HttpServletRequest;
/**
* The DataViewFormSectionController provides methods to display a data view in
* as a
* custom form section
*
* @see pages/workitems/sections/dataview.xhtml
* @author rsoika
* @version 1.0
*/
@Named
@ConversationScoped
public class DataViewSectionController implements Serializable {
private static final long serialVersionUID = 1L;
public static final int MAX_SEARCH_RESULT = 1000;
public static Logger logger = Logger.getLogger(DataViewSectionController.class.getName());
@Inject
WorkflowController workflowController;
@Inject
private Conversation conversation;
@Inject
DataViewService dataViewService;
private Map<String, DataViewSectionDataSet> dataSets = null;
@PostConstruct
public void init() {
startConversation();
dataSets = new HashMap<>();
}
/**
* Starts a new conversation
*/
protected void startConversation() {
if (conversation.isTransient()) {
conversation.setTimeout(
((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest())
.getSession().getMaxInactiveInterval() * 1000);
conversation.begin();
logger.log(Level.FINEST, "......start new conversation, id={0}",
conversation.getId());
}
}
/**
* Returns a single value from a Option key/value list
*
* @param options - options
* @param key - option key
* @return option value
*/
public String getOptionValue(String options, String key) {
// Null checks
if (options == null || key == null || options.trim().isEmpty() || key.trim().isEmpty()) {
return null;
}
// Split options into key/value pairs (separated by semicolon)
String[] pairs = options.split(";");
for (String pair : pairs) {
// Split each pair into key and value (separated by equals sign)
String[] keyValue = pair.split("=", 2); // Limit to 2 in case value contains "="
if (keyValue.length == 2) {
String currentKey = keyValue[0].trim();
String currentValue = keyValue[1].trim();
// Check if the searched key was found
if (key.equals(currentKey)) {
return currentValue;
}
}
}
// Key not found
return null;
}
/**
* Initializes a new DataViewSectionDataSet based on the given options
* (parameter 'name').
*
* The expected format of the options string is:
* <p>
* "name=DATAVIEWNAME"
* <p>
* The method loads the corresponding dataView definition immediately and stores
* the dataSet in a local cache.
*
* @return view result
* @throws QueryException
*/
public DataViewSectionDataSet loadDataSet(String options) throws QueryException {
DataViewSectionDataSet dataSet = dataSets.get(options);
// Extract and set dataViewName from options
if (dataSet == null) {
String _dataViewName = getOptionValue(options, "name");
if (_dataViewName != null) {
logger.info("...build new dataSet by options: " + options);
dataSet = new DataViewSectionDataSet(_dataViewName, workflowController.getWorkitem(), dataViewService);
dataSets.put(options, dataSet);
}
}
return dataSet;
}
public boolean hasDataSet(String options) {
DataViewSectionDataSet dataSet = dataSets.get(options);
// Extract and set dataViewName from options
if (dataSet != null) {
return true;
}
// test if view exists..
String _dataViewName = getOptionValue(options, "name");
if (dataViewService.loadDataViewDefinition(_dataViewName) != null) {
return true;
}
return false;
}
}

View file

@ -1,260 +0,0 @@
package org.imixs.workflow.office.forms;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.logging.Logger;
import org.imixs.workflow.FileData;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.dataview.DataViewController;
import org.imixs.workflow.dataview.DataViewExportEvent;
import org.imixs.workflow.dataview.DataViewPOIHelper;
import org.imixs.workflow.dataview.DataViewService;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
public class DataViewSectionDataSet implements Serializable {
private static final long serialVersionUID = 1L;
public static Logger logger = Logger.getLogger(DataViewSectionController.class.getName());
List<ItemCollection> data = null;
private ItemCollection dataViewDefinition;
private String dataViewName;
private List<ItemCollection> viewItemDefinitions = null;
private String query = null;
private boolean endOfList = false;
private long totalCount = 0;
private long totalPages = 0;
private String sortBy = null;
private boolean sortReverse = false;
private int pageSize = 10;
private int pageIndex = 0;
private DataViewService dataViewService;
private ItemCollection workitem;
public DataViewSectionDataSet(String dataViewName, ItemCollection workitem, DataViewService dataViewService) {
this.dataViewName = dataViewName;
this.workitem = workitem;
this.dataViewService = dataViewService;
dataViewDefinition = dataViewService.loadDataViewDefinition(dataViewName);
boolean debug = dataViewDefinition.getItemValueBoolean("debug");
if (debug) {
logger.info("resolve query by dataView '" + dataViewName + "'");
}
// preload the viewItem definitions
viewItemDefinitions = this.dataViewService.computeDataViewItemDefinitions(dataViewDefinition);
// resove query by dataView
query = this.dataViewService.parseQuery(dataViewDefinition, this.workitem);
loadData();
}
public void forward() {
if (!isEndOfList()) {
pageIndex++;
loadData();
}
}
public void back() {
if (pageIndex > 0) {
pageIndex--;
loadData();
}
}
/**
* load current page
*/
private void loadData() {
try {
data = dataViewService.getWorkflowService().getDocumentService().find(query, getPageSize(), getPageIndex(),
getSortBy(), isSortReverse());
// The end of a list is reached when the size is below or equal the
// pageSize. See issue #287
totalCount = dataViewService.getWorkflowService().getDocumentService().count(query);
totalPages = (long) Math.ceil((double) totalCount / pageSize);
if (data.size() < pageSize) {
setEndOfList(true);
} else {
// look ahead if we have more entries...
int iAhead = (getPageSize() * (getPageIndex() + 1)) + 1;
if (totalCount < iAhead) {
// there is no more data
setEndOfList(true);
} else {
setEndOfList(false);
}
}
} catch (QueryException e) {
logger.warning("Failed to load data: " + e.getMessage());
}
}
public List<ItemCollection> getData() {
return data;
}
public ItemCollection getDataViewDefinition() {
return dataViewDefinition;
}
public long getTotalCount() {
return totalCount;
}
public long getTotalPages() {
return totalPages;
}
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public boolean isEndOfList() {
return endOfList;
}
public void setEndOfList(boolean endOfList) {
this.endOfList = endOfList;
}
public String getDataViewName() {
return dataViewName;
}
public List<ItemCollection> getViewItemDefinitions() {
return viewItemDefinitions;
}
/**
* returns the maximum size of a search result
*
* @return
*/
public int getPageSize() {
return pageSize;
}
/**
* set the maximum size of a search result
*
* @param searchCount
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public String getSortBy() {
return sortBy;
}
public void setSortBy(String sortBy) {
this.sortBy = sortBy;
}
public boolean isSortReverse() {
return sortReverse;
}
public void setSortReverse(boolean sortReverse) {
this.sortReverse = sortReverse;
}
/**
* Exports data into a excel template processed by apache-poi. The method sends
* a DataViewExport event to allow clients to adapt the export process.
*
* @see DataViewExportEvent
*
* @throws PluginException
* @throws QueryException
*/
public String export() throws PluginException, QueryException {
// Build target filename
boolean debug = dataViewDefinition.getItemValueBoolean("debug");
// start export
if (debug) {
logger.info("│ ├── Query: " + query);
}
try {
// test if query exceeds max count
int totalCount = dataViewService.getWorkflowService().getDocumentService().count(query);
// start export
if (debug) {
logger.info("│ ├── Count: " + totalCount);
}
if (totalCount > DataViewService.MAX_ROWS) {
throw new PluginException(DataViewController.class.getSimpleName(), DataViewService.ERROR_CONFIG,
"Data can not be exported into Excel because dataset exceeds " + DataViewService.MAX_ROWS
+ " rows!");
}
String sortBy = dataViewDefinition.getItemValueString("sort.by");
if (sortBy.isEmpty()) {
sortBy = "$modified"; // default
}
List<ItemCollection> workitems = dataViewService.getWorkflowService().getDocumentService().find(query,
DataViewService.MAX_ROWS, 0, sortBy,
dataViewDefinition.getItemValueBoolean("sort.reverse"));
FileData fileDataExport = dataViewService.poiExport(workitems, dataViewDefinition, viewItemDefinitions);
// create a temp event
ItemCollection event = new ItemCollection().setItemValue("txtActivityResult",
dataViewDefinition.getItemValue("poi.update"));
ItemCollection poiConfig = dataViewService.getWorkflowService().evalWorkflowResult(event, "poi-update",
dataViewDefinition,
false);
// merge workitem fields (Workaround because custom forms did hard coded map to
// workflowController instead of workitem
DataViewPOIHelper.poiUpdate(workitem, fileDataExport, poiConfig, dataViewService.getWorkflowService());
if (debug) {
logger.info("├── POI Export completed!");
}
// See:
// https://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean
DataViewPOIHelper.downloadExcelFile(fileDataExport);
} catch (IOException | QueryException e) {
throw new PluginException(DataViewController.class.getSimpleName(), DataViewService.ERROR_CONFIG,
"Failed to generate Excel Export: " + e.getMessage());
}
// return "/pages/admin/excel_export_rechnungsausgang.jsf?faces-redirect=true";
return "";
}
/**
* Returns true if a poi export is defined
*
* @return
*/
public boolean hasPoiExport() {
if (dataViewDefinition != null && !dataViewDefinition.getItemValueString("poi.targetfilename").isBlank()) {
return true;
}
return false;
}
}

View file

@ -1,139 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>office-alexander-logistics</artifactId>
<groupId>com.alexander-logistics</groupId>
<version>1.3.5</version>
</parent>
<artifactId>office-alexander-logistics-testclient</artifactId>
<packaging>jar</packaging>
<name>Imixs Office Workflow Remote Test Client</name>
<build>
<resources>
<!-- enable resource filtering for multi language version -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<!-- use JDK settings for compiling -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!-- Testing JUnit 5 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>
</plugins>
<finalName>imixs-process-manager</finalName>
</build>
<dependencies>
<!-- JEE Dependencies -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
<!-- Imixs Workflow -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-core</artifactId>
<version>${org.imixs.workflow.version}</version>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-melman</artifactId>
<version>${org.imixs.melman.version}</version>
</dependency>
<!-- JUnit 5 Dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<!-- Mockito Dependencies -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.parsson</groupId>
<artifactId>jakarta.json</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
<version>3.1.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>3.1.5</version>
</dependency>
</dependencies>
</project>

View file

@ -1,105 +0,0 @@
package com.alexanderlogistics.rest;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.imixs.melman.EventLogClient;
import org.imixs.melman.FormAuthenticator;
import org.imixs.melman.RestAPIException;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.exceptions.PluginException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
/**
* A test to explore a corgosoft invoice event
*
*/
@Disabled
public class TestCargosoftEvents {
private static Logger logger = Logger.getLogger(TestCargosoftEvents.class.getName());
EventLogClient client = null;
String restAPI = "https://test.alexander-logistics.office-workflow.de/api";
// String restAPI = "http://localhost:8080/api";
String userID = "kutzner-service";
String password = "imixs";
/**
* Setup a new Rest Client
*
* @throws PluginException
*/
@BeforeEach
public void setup() throws PluginException {
client = new EventLogClient(restAPI);
FormAuthenticator aut;
try {
aut = new FormAuthenticator(restAPI, userID, password);
client.registerClientRequestFilter(aut);
} catch (RestAPIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Disabled
@Test
public void getXMLData() {
logger.info("start...");
try {
List<ItemCollection> list = client.searchEventLog("TOPIC_CARGOSOFT_INVOICE");
logger.info("found " + list.size() + " log entries");
for (ItemCollection entry : list) {
List<?> dataList = entry.getItemValue("data");
if (dataList != null && dataList.size() > 0) {
ItemCollection data = new ItemCollection((Map<String, List<Object>>) dataList.get(0));
logger.info("Data=" + data.getItemValueString("some-data"));
logger.info("XML Data=" + data.getItemValueString("xml-data"));
}
}
} catch (RestAPIException e) {
logger.severe("Failed to read event log entry: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Deletes the 10 last topics
*/
@Test
public void deleteXMLData() {
logger.info("start...");
int count = 0;
try {
client.setPageSize(1000);
List<ItemCollection> list = client.searchEventLog("topictest", "TOPIC_CARGOSOFT_INVOICE");
// List<ItemCollection> list = client.searchEventLog("");
logger.info("found " + list.size() + " log entries");
for (ItemCollection entry : list) {
String id = entry.getItemValueString("id");
logger.info("delete event log entry id=" + id);
client.deleteEventLogEntry(id);
count++;
if (count >= 635000) {
break;
}
}
logger.info(count + " log entries deleted");
} catch (
RestAPIException e) {
logger.severe("Failed to read event log entry: " + e.getMessage());
e.printStackTrace();
}
}
}

View file

@ -1,101 +0,0 @@
package com.alexanderlogistics.rest;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.imixs.melman.EventLogClient;
import org.imixs.melman.FormAuthenticator;
import org.imixs.melman.RestAPIException;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.WorkflowKernel;
import org.imixs.workflow.exceptions.PluginException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
/**
* A simple example how to create a new event log entry remote.
*
*/
@Disabled
public class TestEventLog {
private static Logger logger = Logger.getLogger(TestEventLog.class.getName());
EventLogClient client = null;
// String restAPI = "https://test.alexander-logistics.office-workflow.de/api";
String restAPI = "http://localhost:8080/api";
String userID = "kutzner-service";
String password = "imixs";
/**
* Setup a new Rest Client
*
* @throws PluginException
*/
@BeforeEach
public void setup() throws PluginException {
client = new EventLogClient(restAPI);
FormAuthenticator aut;
try {
aut = new FormAuthenticator(restAPI, userID, password);
client.registerClientRequestFilter(aut);
} catch (RestAPIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Create an event log entry....
*
*/
@Test
public void sendXMLData() {
logger.info("start...");
ItemCollection payLoad = new ItemCollection();
String uid = WorkflowKernel.generateUniqueID();
try {
// set data....
payLoad.setItemValue("some-data", "abc");
String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<Invoices>"
+ " <InvoiceHeader>"
+ " <InvoiceNumber>224225</InvoiceNumber>"
+ " </InvoiceHeader>"
+ " </Invoices>";
payLoad.setItemValue("xml-data", xmlString);
client.createEventLogEntry("TOPIC_CARGOSOFT_INVOICE", uid, payLoad);
logger.info("completed");
} catch (RestAPIException e) {
logger.severe("Failed to send event log entry: " + e.getMessage());
e.printStackTrace();
}
}
@Test
public void getXMLData() {
logger.info("start...");
try {
List<ItemCollection> list = client.searchEventLog("TOPIC_CARGOSOFT_INVOICE");
logger.info("found " + list.size() + " log entries");
for (ItemCollection entry : list) {
List<?> dataList = entry.getItemValue("data");
if (dataList != null && dataList.size() > 0) {
ItemCollection data = new ItemCollection((Map<String, List<Object>>) dataList.get(0));
logger.info("Data=" + data.getItemValueString("some-data"));
logger.info("XML Data=" + data.getItemValueString("xml-data"));
}
}
} catch (RestAPIException e) {
logger.severe("Failed to read event log entry: " + e.getMessage());
e.printStackTrace();
}
}
}

View file

@ -1,88 +0,0 @@
package com.alexanderlogistics.rest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
import org.imixs.melman.FormAuthenticator;
import org.imixs.melman.RestAPIException;
import org.imixs.melman.WorkflowClient;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.xml.XMLDataCollectionAdapter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import jakarta.xml.bind.JAXBException;
/**
* A simple example how to send an invoice document remote.
*
*/
@Disabled
public class TestSendInvoice {
private static Logger logger = Logger.getLogger(TestSendInvoice.class.getName());
WorkflowClient client = null;
// String restAPI = "https://test.alexander-logistics.office-workflow.de/api";
String restAPI = "http://localhost:8080/api";
String userID = "kutzner-service";
String password = "imixs";
/**
* Setup a new Rest Client
*
* @throws PluginException
*/
@BeforeEach
public void setup() throws PluginException {
client = new WorkflowClient(restAPI);
FormAuthenticator aut;
try {
aut = new FormAuthenticator(restAPI, userID, password);
client.registerClientRequestFilter(aut);
} catch (RestAPIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Create an event log entry....
*
*/
@Test
public void sendXMLData() {
logger.info("send invoice...");
ItemCollection payLoad = new ItemCollection();
ItemCollection result = null;
try {
// read test data
List<ItemCollection> col = null;
// read default content
col = XMLDataCollectionAdapter
.readCollectionFromInputStream(getClass().getResourceAsStream("/invoice-01.xml"));
assertEquals(1, col.size());
// set invoice data....
// XMLDataCollection result = client.postXMLDocument("workflow/workitem",
// XMLDocumentAdapter.getDocument(col.get(0)));
result = client.processWorkitem(col.get(0));
logger.info("completed");
} catch (RestAPIException | JAXBException | IOException e) {
logger.severe("Failed to send event log entry: " + e.getMessage());
fail(e);
}
}
}

View file

@ -1,187 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<document>
<!-- Workflow -->
<item name="type">
<value xsi:type="xs:string">workitem</value>
</item>
<item name="$workflowgroup">
<value xsi:type="xs:string">Rechnungsausgang</value>
</item>
<item name="$taskid">
<value xsi:type="xs:int">5001</value>
</item>
<item name="$eventid">
<value xsi:type="xs:int">980</value>
</item>
<!-- Dateianhänge -->
<item name="$file">
<value xsi:type="xmlItemArray">
<item name="001_245956_250901_R.pdf">
<value xsi:type="xs:string">application/pdf</value>
<value xsi:type="xs:base64Binary">
JVBERi0xLjMgCiXi48............................
</value>
</item>
</value>
</item>
<!-- Rechnungspositionen -->
<item name="_childitems">
<value xsi:type="xmlItemArray">
<item name="billingcode">
<value xsi:type="xs:string">NACHL40</value>
</item>
<item name="datev.wkz">
<value xsi:type="xs:string">EUR</value>
</item>
<item name="datev.umsatz">
<value xsi:type="xs:double">252.84</value>
</item>
<item name="billingtext">
<value xsi:type="xs:string">Container transport from port</value>
<value xsi:type="xs:string">to warehouse in Antwerp</value>
</item>
<item name="datev.shzeichen">
<value xsi:type="xs:string">H</value>
</item>
<item name="category">
<value xsi:type="xs:string">SEE</value>
</item>
<item name="datev.text">
<value xsi:type="xs:string">LA-PAP-2508-012</value>
</item>
</value>
<value xsi:type="xmlItemArray">
<item name="billingcode">
<value xsi:type="xs:string">FC</value>
</item>
<item name="datev.wkz">
<value xsi:type="xs:string">EUR</value>
</item>
<item name="datev.umsatz">
<value xsi:type="xs:double">22.38</value>
</item>
<item name="billingtext">
<value xsi:type="xs:string">Fuel Charge as per fuel floater August</value>
<value xsi:type="xs:string">2025</value>
</item>
<item name="datev.shzeichen">
<value xsi:type="xs:string">H</value>
</item>
<item name="category">
<value xsi:type="xs:string">DIESEL</value>
</item>
<item name="datev.text">
<value xsi:type="xs:string">LA-PAP-2508-012</value>
</item>
</value>
<value xsi:type="xmlItemArray">
<item name="billingcode">
<value xsi:type="xs:string">ZOLLABF</value>
</item>
<item name="datev.wkz">
<value xsi:type="xs:string">EUR</value>
</item>
<item name="datev.umsatz">
<value xsi:type="xs:double">16.2</value>
</item>
<item name="billingtext">
<value xsi:type="xs:string">custom clearance fiscal representation</value>
<value xsi:type="xs:string">VAT reporting</value>
</item>
<item name="datev.shzeichen">
<value xsi:type="xs:string">H</value>
</item>
<item name="category">
<value xsi:type="xs:string">SEE</value>
</item>
<item name="datev.text">
<value xsi:type="xs:string">LA-PAP-2508-012</value>
</item>
</value>
</item>
<!-- Fachdaten -->
<item name="dbtr.name">
<value xsi:type="xs:string">Graphic Packaging International (NL)</value>
</item>
<item name="dbtr.number">
<value xsi:type="xs:string">D12495</value>
</item>
<item name="invoice.base.amount">
<value xsi:type="xs:double">0.0</value>
</item>
<item name="invoice.bookingperiod">
<value xsi:type="xs:string">202508</value>
</item>
<item name="invoice.costunit">
<value xsi:type="xs:string">IM-ZEL</value>
</item>
<item name="invoice.country">
<value xsi:type="xs:string" />
</item>
<item name="invoice.currency">
<value xsi:type="xs:string">EUR</value>
</item>
<item name="invoice.date">
<value xsi:type="xs:dateTime">2025-09-01T00:00:00+02:00</value>
</item>
<item name="invoice.duedate">
<value xsi:type="xs:dateTime">2025-10-16T00:00:00+02:00</value>
</item>
<item name="invoice.language">
<value xsi:type="xs:string">EN</value>
</item>
<item name="invoice.number">
<value xsi:type="xs:string">245956</value>
</item>
<item name="invoice.positions">
<value xsi:type="xs:string">LA-PAP-2508-012</value>
<value xsi:type="xs:string">LA-PAP-2508-012</value>
<value xsi:type="xs:string">LA-PAP-2508-012</value>
</item>
<item name="invoice.rate">
<value xsi:type="xs:double">0.0</value>
</item>
<item name="invoice.reminder">
<value xsi:type="xs:dateTime">2025-10-16T00:00:00+02:00</value>
</item>
<item name="invoice.saldo">
<value xsi:type="xs:double">469.07</value>
</item>
<item name="invoice.text">
<value xsi:type="xs:string">LA-PAP-2508-012</value>
</item>
<item name="invoice.total">
<value xsi:type="xs:double">469.07</value>
</item>
<item name="invoice.total.net">
<value xsi:type="xs:double">469.07</value>
</item>
<item name="invoice.total.tax">
<value xsi:type="xs:double">0.0</value>
</item>
<item name="invoice.type">
<value xsi:type="xs:string">R</value>
</item>
<item name="invoice.type.description">
<value xsi:type="xs:string">Ausgangsrechnung</value>
</item>
<item name="invoice.vatrate">
<value xsi:type="xs:double">0.0</value>
</item>
<item name="mandant.id">
<value xsi:type="xs:string">001</value>
</item>
<item name="payment.term">
<value xsi:type="xs:string">10</value>
</item>
</document>
</data>

587
pom.xml
View file

@ -5,40 +5,73 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.alexander-logistics</groupId>
<artifactId>office-alexander-logistics</artifactId>
<version>1.3.5</version>
<packaging>pom</packaging>
<version>1.4.0</version>
<packaging>war</packaging>
<name>Imixs Office Workflow - Custom Build</name>
<organization>
<name>Imixs Software Solutions GmbH</name>
<url>http://www.imixs.com</url>
</organization>
<inceptionYear>2024</inceptionYear>
<developers>
<developer>
<id>rsoika</id>
<name>Ralph Soika</name>
<email>ralph.soika@imixs.com</email>
<url>http://blog.imixs.org/</url>
<organization>Imixs Software Solutions GmbH</organization>
<organizationUrl>http://www.imixs.com</organizationUrl>
<roles>
<role>developer</role>
<role>testing</role>
</roles>
<timezone>2</timezone>
</developer>
<developer>
<id>gaheinle</id>
<name>Gaby Heinle</name>
<email />
<url />
<organization>Imixs Software Solutions GmbH</organization>
<organizationUrl>http://www.imixs.com</organizationUrl>
<roles>
<role>developer</role>
<role>testing</role>
</roles>
<timezone>2</timezone>
</developer>
</developers>
<modules>
<module>office-alexander-logistics-app</module>
<module>office-alexander-logistics-testclient</module>
</modules>
<properties>
<java.source>11</java.source>
<java.target>11</java.target>
<java.source>17</java.source>
<java.target>17</java.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Wildfly -->
<custom.webResources>src/main/webapp</custom.webResources>
<custom.unpackTypes>war</custom.unpackTypes>
<!-- Build Time -->
<org.imixs.build.timestamp>${maven.build.timestamp}</org.imixs.build.timestamp>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
<!-- Dependency Versions -->
<jakarta.version>10.0.0</jakarta.version>
<org.imixs.office.version>5.0.5-SNAPSHOT</org.imixs.office.version>
<org.imixs.workflow.version>6.0.9</org.imixs.workflow.version>
<org.imixs.marty.version>5.0.0</org.imixs.marty.version>
<org.imixs.archive.version>3.1.3-SNAPSHOT</org.imixs.archive.version>
<org.imixs.adapters.version>3.0.3</org.imixs.adapters.version>
<org.imixs.melman.version>2.1.1-SNAPSHOT</org.imixs.melman.version>
<org.imixs.data.version>1.0.2-SNAPSHOT</org.imixs.data.version>
<org.imixs.e-invoice.version>1.0.3-SNAPSHOT</org.imixs.e-invoice.version>
<microprofile.version>6.0</microprofile.version>
<net.sf.saxon.version>9.9.1-4</net.sf.saxon.version>
<apache.pdfbox.version>2.0.26</apache.pdfbox.version>
<!-- Dependency Versions -->
<jakarta.version>10.0.0</jakarta.version>
<microprofile.version>6.0</microprofile.version>
<org.imixs.office.version>5.1.9-SNAPSHOT</org.imixs.office.version>
<org.imixs.workflow.version>6.2.8-SNAPSHOT</org.imixs.workflow.version>
<org.imixs.marty.version>5.2.0</org.imixs.marty.version>
<org.imixs.e-invoice.version>1.0.3-SNAPSHOT</org.imixs.e-invoice.version>
<org.imixs.adapter.version>3.2.4-SNAPSHOT</org.imixs.adapter.version>
<org.imixs.data.version>1.0.4-SNAPSHOT</org.imixs.data.version>
<apache.poi.version>4.0.0</apache.poi.version>
<net.sf.saxon.version>9.9.1-4</net.sf.saxon.version>
<apache.pdfbox.version>2.0.24</apache.pdfbox.version>
<!-- -->
<org.imixs.ai.version>1.1.1</org.imixs.ai.version>
<org.imixs.ai.version>1.1.9-SNAPSHOT</org.imixs.ai.version>
<custom.webResources>src/main/webapp</custom.webResources>
<!-- test dependencies -->
@ -56,6 +89,7 @@
<!-- Wildfly unpack war -->
<custom.unpackTypes>war</custom.unpackTypes>
<jakarta.faces.project_stage>Production</jakarta.faces.project_stage>
<!-- jndi Mail res-ref name -->
<imixs-mail-res-ref-name>java:/mail/org.imixs.workflow.mail</imixs-mail-res-ref-name>
@ -67,9 +101,9 @@
<repositories>
<!-- Sonatype Snapshot repository -->
<repository>
<id>sonatype-snaptshots</id>
<name>Sonatype Snapshot repository</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<id>central-portal-snapshots</id>
<name>Central Portal Snapshots</name>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
@ -82,19 +116,114 @@
<profiles>
<profile>
<id>docker</id>
<!-- build latest - see ear module for details -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<exec executable="docker">
<arg value="build" />
<arg value="-t" />
<arg value="imixs/${imixs-office.applicationname}" />
<arg value="./" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>debug</id>
<!-- build latest - see ear module for details -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<exec executable="docker">
<arg value="build" />
<arg value="-f" />
<arg value="./Dockerfile-debug" />
<arg value="-t" />
<arg value="imixs/${imixs-office.applicationname}" />
<arg value="./." />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>kubernetes</id>
<!-- build and push to rep - see ear module for details -->
<id>imixs-cloud</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<exec executable="docker">
<arg value="build" />
<arg value="-t" />
<arg
value="imixs/${imixs-office.applicationname}:${project.version}" />
<arg value="./." />
</exec>
<exec executable="docker">
<arg value="tag" />
<arg
value="imixs/${imixs-office.applicationname}:${project.version}" />
<arg
value="${org.imixs.kubernetes.registry}/imixs/${imixs-office.applicationname}:${project.version}" />
</exec>
<exec executable="docker">
<arg value="push" />
<arg
value="${org.imixs.kubernetes.registry}/imixs/${imixs-office.applicationname}:${project.version}" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<resources>
<!-- enable resource filtering for multi language version -->
@ -103,7 +232,21 @@
<filtering>true</filtering>
</resource>
</resources>
<testResources>
<testResource>
<directory>${basedir}/./reports</directory>
</testResource>
<testResource>
<directory>${basedir}/./workflow</directory>
</testResource>
<testResource>
<directory>${basedir}/src/test/resources</directory>
</testResource>
</testResources>
<plugins>
<!-- use JDK settings for compiling -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
@ -117,8 +260,59 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<version>3.3.1</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<filtering>true</filtering>
<!-- this is relative to the pom.xml directory -->
<directory>${custom.webResources}</directory>
<includes>
<include>**/WEB-INF/*</include>
<!-- include any other file types you want to filter -->
</includes>
</resource>
</webResources>
<!-- We exclude libs form the parent WAR artifact
<workDirectory>target/overlay-war-folder</workDirectory>
<overlays>
<overlay>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-app</artifactId>
<excludes>
<exclude>WEB-INF/lib/imixs-data-*.jar</exclude>
</excludes>
</overlay>
</overlays>
-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
@ -128,196 +322,49 @@
</configuration>
</plugin>
<!-- 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>
<groupId>org.imixs.maven</groupId>
<artifactId>manik-hotdeploy-maven-plugin</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<phase>validate</phase>
<phase>install</phase>
<goals>
<goal>format</goal>
<goal>deploy</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- List Source and Target folders for Autodeploy and Hotdeploy -->
<autodeployments>
<deployment>
<!-- wildcard deployment -->
<source>target/*.{war,ear,jar}</source>
<target>./docker/deployments/</target>
<unpack>true</unpack>
</deployment>
</autodeployments>
<hotdeployments>
<deployment>
<source>src/main/webapp</source>
<target>./docker/deployments/${imixs-office.applicationname}.war</target>
</deployment>
</hotdeployments>
</configuration>
</plugin>
<!-- relase management -->
<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>
<artifactId>maven-release-plugin</artifactId>
</plugin>
-->
</plugins>
<finalName>office-alexander-logistics</finalName>
<finalName>office-alexander-logistics</finalName>
</build>
<dependencyManagement>
<dependencies>
<!-- Imixs Workflow -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-core</artifactId>
<version>${org.imixs.workflow.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-engine</artifactId>
<version>${org.imixs.workflow.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-faces</artifactId>
<version>${org.imixs.workflow.version}</version>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-jax-rs</artifactId>
<version>${org.imixs.workflow.version}</version>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-workflow-index-lucene</artifactId>
<version>${org.imixs.workflow.version}</version>
</dependency>
<!-- Marty -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-marty</artifactId>
<version>${org.imixs.marty.version}</version>
<scope>provided</scope>
</dependency>
<!-- Office Workflow -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-app</artifactId>
<version>${org.imixs.office.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-util</artifactId>
<version>${org.imixs.office.version}</version>
<scope>provided</scope>
</dependency>
<!-- SEPA Adapter -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-sepa</artifactId>
<version>${org.imixs.adapters.version}</version>
<scope>provided</scope>
</dependency>
<!-- DATEV Adapter -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-datev</artifactId>
<version>${org.imixs.adapters.version}</version>
<scope>provided</scope>
</dependency>
<!-- QR Code -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-qrcode</artifactId>
<version>${org.imixs.adapters.version}</version>
<scope>provided</scope>
</dependency>
<!-- POI Adapter -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-poi</artifactId>
<version>${org.imixs.adapters.version}</version>
<scope>provided</scope>
</dependency>
<!-- Imixs-Archive API -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-archive-api</artifactId>
<version>${org.imixs.archive.version}</version>
<scope>provided</scope>
</dependency>
<!-- Imixs AI -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-ai-workflow</artifactId>
<version>${org.imixs.ai.version}</version>
<scope>compile</scope>
</dependency>
<!-- Imixs Data -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-groups</artifactId>
<version>${org.imixs.data.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-views</artifactId>
<version>${org.imixs.data.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-documents</artifactId>
<version>${org.imixs.data.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-importer</artifactId>
<version>${org.imixs.data.version}</version>
<scope>compile</scope>
</dependency>
<!-- Melman Version Management hinzufügen -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-melman</artifactId>
<version>${org.imixs.melman.version}</version>
<scope>compile</scope>
</dependency>
<!-- xsl 2.0 support for Reporting / Chart Diagrams -->
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>${net.sf.saxon.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Jakarta EE -->
<dependency>
@ -326,8 +373,6 @@
<version>${jakarta.version}</version>
<scope>provided</scope>
</dependency>
<!-- Microprofile -->
<dependency>
<groupId>org.eclipse.microprofile</groupId>
@ -337,6 +382,131 @@
<scope>provided</scope>
</dependency>
<!-- Imixs-Office-Workflow Overlay -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-app</artifactId>
<type>war</type>
<version>${org.imixs.office.version}</version>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-office-workflow-util</artifactId>
<version>${org.imixs.office.version}</version>
</dependency>
<!-- Imixs Data -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-data-importer</artifactId>
<version>${org.imixs.data.version}</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>${apache.pdfbox.version}</version>
</dependency>
<!-- Imixs-AI -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-ai-workflow</artifactId>
<version>${org.imixs.ai.version}</version>
</dependency>
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-ai-bpmn</artifactId>
<version>${org.imixs.ai.version}</version>
</dependency>
<!-- SEPA -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-sepa</artifactId>
<version>${org.imixs.adapter.version}</version>
</dependency>
<!-- DATEV -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-datev</artifactId>
<version>${org.imixs.adapter.version}</version>
</dependency>
<!-- POI Adapter
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-poi</artifactId>
<version>${org.imixs.adapter.version}</version>
</dependency>
-->
<!-- QR Code -->
<dependency>
<groupId>org.imixs.workflow</groupId>
<artifactId>imixs-adapters-qrcode</artifactId>
<version>${org.imixs.adapter.version}</version>
</dependency>
<!-- E-Invoice-->
<dependency>
<groupId>org.imixs.util</groupId>
<artifactId>imixs-e-invoice</artifactId>
<version>${org.imixs.e-invoice.version}</version>
</dependency>
<!-- Apache Commons FTP Client -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<!-- Microsoft oauth token -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
<scope>test</scope>
</dependency>
<!-- JAX-RS 2.0 Test dependencies -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.3.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<!-- Testing -->
<!-- JUnit 5 Dependencies -->
@ -365,7 +535,6 @@
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.eclipse.parsson</groupId>
<artifactId>jakarta.json</artifactId>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0">
<xsl:strip-space elements="*" />
<xsl:output method="xml" indent="yes" encoding="UTF-8"
standalone="yes" />
<xsl:template match="/">
<xsl:variable name="date"
select="/data/document/item[@name='$modified']/value" />
<Invoices version="2020.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Message>
<SenderID>Imixs-Office-Workflow</SenderID>
<ReceiverID>Cargosoft</ReceiverID>
<MessageID>
<xsl:value-of select="/data/document/item[@name='$uniqueid']/value" />
</MessageID>
<MessageDate>
<DateTime>
<xsl:value-of select="$date" />
</DateTime>
</MessageDate>
</Message>
<xsl:apply-templates
select="/data/document[normalize-space(item[@name = '$workflowgroup']/value) =
'Cargosoft-Export']" />
</Invoices>
</xsl:template>
<!-- This template builds invoice info -->
<xsl:template
match="/data/document[normalize-space(item[@name = '$workflowgroup']/value) =
'Cargosoft-Export']">
<xsl:variable name="date" select="item[@name='$modified']/value" />
<xsl:variable
name="currency" select="item[@name='invoice.currency']/value" />
<Invoice>
<InvoiceHeader>
<Client>
<Codes>
<!-- Als Typ muss „cs“ übermittelt werden und im Code wird
dann der Cargosoft Mandant erwartet. -->
<Code Type="cs">008</Code>
</Codes>
</Client>
<!-- Hier muss eine eindeutige Belegnummer für jeden einzelnen
Beleg übermittelt werden. Es muss sich um eine Nummer
handeln, die pro Beleg hochgezählt wird und darf sich nicht
überschneiden mit dem CargoSoft Belegnummernkreis.
Daher den Nummernkreis vorher mit CargoSoft absprechen. -->
<InvoiceNumber>
<xsl:value-of select="item[@name='numsequencenumber']/value" />
</InvoiceNumber>
<!-- Belegart - bei Gutschriften 'CREDIT' andernfalls 'INVOICE -->
<InvoiceType>
<Codes>
<xsl:choose>
<xsl:when test="item[@name='payment.type']/value = 'credit'">
<Code Type="cs">CREDIT</Code>
</xsl:when>
<xsl:otherwise>
<Code Type="cs">INVOICE</Code>
</xsl:otherwise>
</xsl:choose>
</Codes>
</InvoiceType>
<InvoiceCurrency>
<Codes>
<Code Type="cs">
<xsl:value-of select="$currency" />
</Code>
</Codes>
</InvoiceCurrency>
<InvoiceAmount>
<NetAmount>
<Amount>
<Currency>
<Codes>
<Code Type="cs">
<xsl:value-of select="$currency" />
</Code>
</Codes>
</Currency>
<Value>
<xsl:value-of select="item[@name='order.total.netto']/value"
/>
</Value>
<!-- exchange rate nur ausgeben wenn vorhanden -->
<xsl:if
test="string-length(item[@name='invoice.exchangerate']/value) >0">
<ExchangeRate>
<xsl:value-of select="item[@name='invoice.exchangerate']/value" />
</ExchangeRate>
</xsl:if>
</Amount>
</NetAmount>
<VATInformation>
<VATAmount>
<Amount>
<Currency>
<Codes>
<Code Type="cs">
<xsl:value-of select="$currency" />
</Code>
</Codes>
</Currency>
<Value>
<xsl:value-of select="item[@name='order.total.tax']/value" />
</Value>
<!-- exchange rate nur ausgeben wenn vorhanden -->
<xsl:if
test="string-length(item[@name='invoice.exchangerate']/value) >0">
<ExchangeRate>
<xsl:value-of
select="item[@name='invoice.exchangerate']/value" />
</ExchangeRate>
</xsl:if>
</Amount>
</VATAmount>
</VATInformation>
</InvoiceAmount>
<CollectionInvoice>false</CollectionInvoice>
<xsl:if test="string-length(item[@name='invoice.period']/value) > 0">
<BookingPeriod>
<xsl:value-of select="item[@name='invoice.period']/value" />
</BookingPeriod>
</xsl:if>
<Booked>false</Booked>
<InvoiceDate>
<xsl:value-of select="item[@name='invoice.date']/value" />
</InvoiceDate>
<InvoiceAddress type="CN">
<Codes>
<Code Type="cs">
<xsl:value-of select="item[@name='cdtr.number']/value" />
</Code>
</Codes>
</InvoiceAddress>
<References>
<Reference type="cs">
<xsl:value-of select="item[@name='invoice.number']/value" />
</Reference>
</References>
<!-- Attachements -->
<xsl:if test="item[@name='$file.count']/value > 0">
<Attachments>
<xsl:for-each
select="item[@name='$file']/value/item">
<Attachment>
<xsl:attribute name="id"><xsl:value-of
select="./value/item[@name='md5checksum']/value" /></xsl:attribute>
<xsl:attribute name="version">1</xsl:attribute>
<Filename>
<xsl:value-of select="lower-case(./@name)" />
</Filename>
<Description>Imixs-Office-Workflow</Description>
<Content>
<xsl:value-of select="./value[2]" />
</Content>
</Attachment>
</xsl:for-each>
</Attachments>
</xsl:if>
</InvoiceHeader>
<InvoiceRows>
<xsl:for-each
select="item[@name='_childitems']/value">
<InvoiceRow>
<Row>
<xsl:value-of select="./item[@name='numpos']/value" />
</Row>
<FileNumber>
<xsl:value-of select="./item[@name='name']/value"
/>
</FileNumber>
<InvoiceAmount>
<NetAmount>
<Amount>
<Currency>
<Codes>
<Code Type="cs">
<xsl:value-of select="$currency" />
</Code>
</Codes>
</Currency>
<Value>
<xsl:value-of select="./item[@name='amount']/value" />
</Value>
</Amount>
</NetAmount>
<VATInformation>
<VAT>
<Codes>
<Code Type="cs">
<xsl:value-of select="./item[@name='tax']/value" />
</Code>
</Codes>
</VAT>
</VATInformation>
</InvoiceAmount>
<ActivityType>
<Codes>
<Code Type="cs">
<xsl:value-of select="./item[@name='category']/value" />
</Code>
</Codes>
</ActivityType>
</InvoiceRow>
</xsl:for-each>
</InvoiceRows>
</Invoice>
</xsl:template>
</xsl:stylesheet>

View file

@ -1,523 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 pain.001.001.03.xsd">
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>885e0519099f4ef5876b1b721d4b605f</MsgId>
<CreDtTm>2024-06-20T09:33:46</CreDtTm>
<NbOfTxs>20</NbOfTxs>
<CtrlSum>67913,22</CtrlSum>
<InitgPty>
<Nm>PKO Bank Polski SA (PLN)</Nm>
</InitgPty>
</GrpHdr>
<PmtInf>
<PmtInfId>885e0519099f4ef5876b1b721d4b605f-1</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<NbOfTxs>20</NbOfTxs>
<CtrlSum>67913,22</CtrlSum>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<ReqdExctnDt>2024-06-20</ReqdExctnDt>
<Dbtr>
<Nm>PKO Bank Polski SA (PLN)</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>PL61102010260000120203993128</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>BPKOPLPW</BIC>
</FinInstnId>
</DbtrAgt>
<ChrgBr>SHAR</ChrgBr>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>ALBPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Blaszkiewicz</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL35249000050000453034973384</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701528 / 540/05/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">4059.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>GBWCPLPP</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>KOWALEWSKI</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL33823300040017753920140001</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701515 / FS 318/04/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PKOPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>GEODIS</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL85124062921111001069083502</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701779 / FWA/24FTD/01725</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PKOPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>GEODIS</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL85124062921111001069083502</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701780 / FWA/24FTD/01732</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PKOPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>GEODIS</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL85124062921111001069083502</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701781 / FWA/24FTD/01736</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">3013.50</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>INGBPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>adex</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL42105015911000009135641521</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701800 / FS 34/05/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2952.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PPABPLPK</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Danuta Bedkowska</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL50102024300000860200294058</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701801 / FT/948/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2952.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>INGBPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Easy Way</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL31105017221000009142459099</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701817 / FV/106/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PPABPLPK</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>RABEN</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL67203000745059000010201640</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701809 / 8742530343</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PPABPLPK</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>RABEN</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL67203000745059000010201640</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701808 / 8742530342</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>WBKPPLPP</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>ZASADA TRANS</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL08150017481217400107410000</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701815 / TKP/0211/05/2024/FV</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PPABPLPKXXX</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Wielkopolska</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL73203000451110000002046170</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701802 / V 00043/05/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2337.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PKOPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>EXWIS</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL88124060871111001053542790</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701823 / 381/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">1230.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PKOPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>GEODIS</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL85124062921111001069083502</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701782 / FKA/24FTD/01907</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2029.50</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PKOPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>STALKO</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL51124063351111000051278199</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701813 / 3814/04/2024/TR</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">2029.50</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PKOPPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>STALKO</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL51124063351111000051278199</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701811 / 3812/04/2024/TR</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">3075.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>POLUPLPR</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Klajnowski</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL21888210322001002691790001</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>701816 / 751/2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">1848.00</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>INGBPLPW</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>BULK CARGO</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL97105000995381000010009580</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>702441 / VAT/2043/E /2024</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">16961.40</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PPABPLPK</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Baltic Hub</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL52160014753166100000000793</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>702466 / FV/24/06/0304</Ustrd>
</RmtInf>
</CdtTrfTxInf>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="PLN">6730.32</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>PPABPLPK</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>Baltic Hub</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>PL52160014753166100000000793</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>702467 / FV/24/06/0309</Ustrd>
</RmtInf>
</CdtTrfTxInf>
</PmtInf>
</CstmrCdtTrfInitn>
</Document>

View file

@ -1,20 +0,0 @@
#!/bin/bash
############################################################
# Setup Imixs-Documents Training Environment
#
############################################################
sudo chmod -R 777 docker/deployments/
echo "#############################################"
echo " building Imixs-ML Docker images..."
echo "#############################################"
mvn -f ~/git/imixs-ml/ clean install -Pdocker -DskipTests
echo "#############################################"
echo " starting dev enrvionment..."
echo "#############################################"
mvn clean install -Pdebug
cp ./*-app/target/*.war ./docker/deployments/
docker-compose -f docker-compose.yml up

View file

@ -0,0 +1,167 @@
package com.alexanderlogistics;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.SignalAdapter;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.exceptions.AdapterException;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
import com.alexanderlogistics.mahnlauf.MahnlaufService;
import jakarta.inject.Inject;
/**
* Der AGLAIInvoiceAdapter weist eien Rechnung dem richtigen Space zu und sucht
* nach dem passenden Business Partner
*
*
*
* @version 1.0
* @author rsoika
*/
public class AGLAIInvoiceAdapter implements SignalAdapter {
private static Logger logger = Logger.getLogger(AGLAIInvoiceAdapter.class.getName());
public static final String ERROR_MISSING_DATA = "MISSING_DATA";
public static final String ERROR_CONFIG = "CONFIG_ERROR";
@Inject
MahnlaufService mahnlaufService;
@Inject
DocumentService documentService;
/**
* This method finds or create the Zahlungsavis and adds a reference
* ($workitemref) to the current invoice.
*
* @throws PluginException
*/
@Override
public ItemCollection execute(ItemCollection workitem, ItemCollection event)
throws AdapterException, PluginException {
// Inbound Invoice?
if (workitem.getModelVersion().startsWith("rechnungseingang")) {
// Initialize invoice.positions and Space
initInvoicePositions(workitem);
initInvoiceSpace(workitem);
initInvoiceBusinessPartner(workitem);
}
return workitem;
}
/**
* Diese Methode prüft ob es bei einer Eingangsrechnung zwar das feld
* 'invoice.positions' gibt, aber noch keine Positionsliste
* Die Methode erzeugt eine Default Zeile.
*
* @param workitem
*/
private void initInvoicePositions(ItemCollection workitem) {
List<ItemCollection> childList = InvoiceUtil.explodeChildList(workitem);
if (childList.size() == 0 && !workitem.getItemValueString("invoice.positions").isEmpty()) {
String positionNumber = workitem.getItemValueString("invoice.positions");
logger.info("├── init invoice.positions: " + positionNumber);
ItemCollection child = new ItemCollection();
child.setItemValue("numPos", 1);
child.setItemValue("name", positionNumber);
childList.add(child);
InvoiceUtil.implodeChildList(workitem, childList);
}
}
/**
* Die Methode findet den passenden Space anhand
* der REgex in space sofern das workitem noch keinem Space zugewiesen ist
*
* @param workitem
*/
private void initInvoiceSpace(ItemCollection workitem) {
if (workitem.getItemValueString("space.ref").isEmpty()
&& !workitem.getItemValueString("invoice.positions").isEmpty()) {
String positionNumber = workitem.getItemValueString("invoice.positions");
logger.info("├── init space for position : " + positionNumber);
// Jetzt noch das Space mapping
Map<String, List<String>> spacePosMappings = mahnlaufService.loadSpacePosMappings();
mahnlaufService.mapInvoiceTextToSpace(workitem, spacePosMappings, positionNumber);
}
}
/**
* Find creditor cdtr.name
* based on the field
* 'document.company' or cdtr.name
*
* Zunächst versuchen wir falls ein cdtr.name von der KI gefunden wurde dieesn
* über das Businesspartner Interface aufzulösne.
* Falls das nicht gelingt, suchen wir nach einer alten Rechnung mit der selben
* document.company
*
*/
private void initInvoiceBusinessPartner(ItemCollection workitem) {
if (workitem.getItemValueString("partner.id").isEmpty()
&& !workitem.getItemValueString("document.company").isEmpty()) {
String companyName = workitem.getItemValueString("document.company");
String cdtrName = workitem.getItemValueString("cdtr.name");
logger.info("├── init cdtr.name for document.company: " + companyName);
// erster versuch über Busienss partner.
String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:businesspartner*) AND (partner.name:\""
+ cdtrName + "\")";
try {
List<ItemCollection> result = documentService.find(query, 1, 0, "$created", true);
if (result.size() == 1) {
logger.info("│ ├── found business partner by cdtr.name");
ItemCollection businessPartner = result.get(0);
workitem.setItemValue("cdtr.number", businessPartner.getItemValueString("cdtr.number"));
workitem.setItemValue("cdtr.name", businessPartner.getItemValueString("cdtr.name"));
workitem.setItemValue("partner.id", businessPartner.getItemValueString("partner.id"));
workitem.setItemValue("partner.name", businessPartner.getItemValueString("cdtr.name"));
return;
}
} catch (QueryException e) {
// not found!
logger.warning("Failed to lookup company name '" + companyName + "' : " + e.getMessage());
}
// Eine Suche über den exakten Namen ist sinnlos gewesen, daher versuchen wir
// nun über den letzten Treffer
query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND (document.company:\""
+ companyName + "\") AND NOT (partner.id=\"\") AND ($taskid:[5010 TO 5900])";
try {
List<ItemCollection> result = documentService.find(query, 1, 0, "$created", true);
if (result.size() == 1) {
logger.info("│ ├── found business partner by last invoice");
ItemCollection invoice = result.get(0);
workitem.setItemValue("cdtr.number", invoice.getItemValueString("cdtr.number"));
workitem.setItemValue("cdtr.name", invoice.getItemValueString("cdtr.name"));
workitem.setItemValue("partner.id", invoice.getItemValueString("partner.id"));
workitem.setItemValue("partner.name", invoice.getItemValueString("cdtr.name"));
}
} catch (QueryException e) {
// not found!
logger.warning("Failed to lookup company name '" + companyName + "' : " + e.getMessage());
}
}
}
}

View file

@ -120,55 +120,57 @@ public class AGLAnalyticControllerDebitor implements Serializable {
link = link + "&processref=" + process.getUniqueID() + "&phrase=" + getDbtNr();
}
if ("analytic.invoices.count.all".equals(event.getKey())) {
event.setValue("" + countAll);
event.setLabel(formatTotals(totalAllCurrency1, totalAllCurrency2));
event.setDescription("Total invoices");
event.getWorkitem().setItemValue("invoices.total", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", countAll);
event.getData().setItemValue("label", formatTotals(totalAllCurrency1, totalAllCurrency2));
event.getData().setItemValue("description", "Total invoices");
event.getWorkitem().setItemValue("invoices.total", countAll);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.invoices.count.open".equals(event.getKey())) {
event.setValue("" + countOpen);
event.setLabel(formatTotals(totalOpenCurrency1, totalOpenCurrency2));
event.setDescription("Total invoices not yet in due");
event.getWorkitem().setItemValue("invoices.total.open", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + countOpen);
event.getData().setItemValue("label", formatTotals(totalOpenCurrency1, totalOpenCurrency2));
event.getData().setItemValue("description", "Total invoices not yet in due");
event.getWorkitem().setItemValue("invoices.total.open", countOpen);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.invoices.count.due".equals(event.getKey())) {
event.setValue("" + countDue);
event.setLabel(formatTotals(totalDueCurrency1, totalDueCurrency2));
event.setDescription("Total invoices in due");
event.getWorkitem().setItemValue("invoices.total.due", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + countDue);
event.getData().setItemValue("label", formatTotals(totalDueCurrency1, totalDueCurrency2));
event.getData().setItemValue("description", "Total invoices in due");
event.getWorkitem().setItemValue("invoices.total.due", countDue);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.invoices.count.dunning".equals(event.getKey())) {
event.setValue("" + countDunning);
event.setLabel(formatTotals(totalDunningCurrency1, totalDunningCurrency2));
event.setDescription("Total invoices in dunning");
event.getWorkitem().setItemValue("invoices.total.dunning", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + countDunning);
event.getData().setItemValue("label", formatTotals(totalDunningCurrency1, totalDunningCurrency2));
event.getData().setItemValue("description", "Total invoices in dunning");
event.getWorkitem().setItemValue("invoices.total.dunning", countDunning);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.payment.avg.due".equals(event.getKey())) {
event.setValue("" + averagePaymentDue);
event.setLabel("days");
event.setDescription("Average terms of credit in the last 12 months.");
event.getWorkitem().setItemValue("payment.avg.due", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + averagePaymentDue);
event.getData().setItemValue("label", "days");
event.getData().setItemValue("description", "Average terms of credit in the last 12 months.");
event.getWorkitem().setItemValue("payment.avg.due", averagePaymentDue);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.payment.avg.days".equals(event.getKey())) {
event.setValue("" + averagePaymentDays);
event.setLabel("days");
event.setDescription("Average duration for payment during the last 12 months.");
event.getWorkitem().setItemValue("payment.avg.days", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + averagePaymentDays);
event.getData().setItemValue("label", "days");
event.getData().setItemValue("description", "Average duration for payment during the last 12 months.");
event.getWorkitem().setItemValue("payment.avg.days", averagePaymentDays);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.invoices.trend".equals(event.getKey())) {
event.setValue(chartData);
event.setLabel("Payment duration in days");
event.setDescription("Payment practice by week");
event.getData().setItemValue("value", chartData);
event.getData().setItemValue("label", "Payment duration in days");
event.getData().setItemValue("description", "Payment practice by week");
}
}

View file

@ -100,34 +100,39 @@ public class AGLAnalyticControllerOPListe implements Serializable {
+ "&spaceref=" + departmentID;
}
if ("analytic.invoices.count.all".equals(event.getKey())) {
event.setValue("" + countAll);
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.all"));
event.getWorkitem().setItemValue("invoices.total", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + countAll);
event.getData().setItemValue("label", resourceBundleHandler.findMessage("oplist.invoices"));
event.getData().setItemValue("description",
resourceBundleHandler.findMessage("oplist.invoices.description.all"));
event.getWorkitem().setItemValue("invoices.total", countAll);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.invoices.count.open".equals(event.getKey())) {
event.setValue("" + (countOpen));
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.open"));
event.getWorkitem().setItemValue("invoices.total.open", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + (countOpen));
event.getData().setItemValue("label", resourceBundleHandler.findMessage("oplist.invoices"));
event.getData().setItemValue("description",
resourceBundleHandler.findMessage("oplist.invoices.description.open"));
event.getWorkitem().setItemValue("invoices.total.open", countOpen);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.invoices.count.due".equals(event.getKey())) {
event.setValue("" + countDue);
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.due"));
event.getWorkitem().setItemValue("invoices.total.due", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + countDue);
event.getData().setItemValue("label", resourceBundleHandler.findMessage("oplist.invoices"));
event.getData().setItemValue("description",
resourceBundleHandler.findMessage("oplist.invoices.description.due"));
event.getWorkitem().setItemValue("invoices.total.due", countDue);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.invoices.count.dunning".equals(event.getKey())) {
event.setValue("" + countDunning);
event.setLabel(resourceBundleHandler.findMessage("oplist.invoices"));
event.setDescription(resourceBundleHandler.findMessage("oplist.invoices.description.dunning"));
event.getWorkitem().setItemValue("invoices.total.dunning", event.getValue());
event.setLink(link);
event.getData().setItemValue("value", "" + countDunning);
event.getData().setItemValue("label", resourceBundleHandler.findMessage("oplist.invoices"));
event.getData().setItemValue("description",
resourceBundleHandler.findMessage("oplist.invoices.description.dunning"));
event.getWorkitem().setItemValue("invoices.total.dunning", countDunning);
event.getWorkitem().setItemValue("link", link);
}
}

View file

@ -69,53 +69,57 @@ public class AGLAnalyticControllerSteuer implements Serializable {
link = link + "?processref=" + process.getUniqueID() + "&workflowgroup=Steuerbescheid";
}
if ("analytic.steuer.eust".equals(event.getKey())) {
event.setValue(computeSteuerbescheideEUST());
event.setLabel("EUR");
event.setDescription("Gesamt Einfuhrumsatzsteuer (EUSt)");
event.getWorkitem().setItemValue("eust.total", event.getValue());
event.setLink(link);
Object eustTotal = computeSteuerbescheideEUST();
event.getData().setItemValue("value", eustTotal);
event.getData().setItemValue("label", "EUR");
event.getData().setItemValue("description", "Gesamt Einfuhrumsatzsteuer (EUSt)");
event.getWorkitem().setItemValue("eust.total", eustTotal);
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.steuer.zoll".equals(event.getKey())) {
event.setValue(computeSteuerbescheideZoll());
event.setLabel("EUR");
event.setDescription("Gesamt Zölle (ZOLLEU)");
event.setLink(link);
event.getData().setItemValue("value", computeSteuerbescheideZoll());
event.getData().setItemValue("label", "EUR");
event.getData().setItemValue("description", "Gesamt Zölle (ZOLLEU)");
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.steuer.total".equals(event.getKey())) {
event.setValue(computeSteuerbescheideTotal());
event.setLabel("EUR");
event.setDescription("Alle Steuerbescheide die noch nicht abgerechnet wurden.");
event.setLink(link);
event.getData().setItemValue("value", computeSteuerbescheideTotal());
event.getData().setItemValue("label", "EUR");
event.getData().setItemValue("description", "Alle Steuerbescheide die noch nicht abgerechnet wurden.");
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.steuer.saldo".equals(event.getKey())) {
event.setValue(computeSteuerbescheideSaldo());
event.setLabel("EUR");
event.setDescription("Saldo aller Steuerbescheide die noch nicht abgerechnet wurden.");
event.setLink(link);
event.getData().setItemValue("value", computeSteuerbescheideSaldo());
event.getData().setItemValue("label", "EUR");
event.getData().setItemValue("description",
"Saldo aller Steuerbescheide die noch nicht abgerechnet wurden.");
event.getWorkitem().setItemValue("link", link);
}
if ("analytic.steuer.due".equals(event.getKey())) {
event.setValue(computeSteuerbescheideSaldoDue());
event.setLabel("EUR");
event.setDescription("Saldo aller überfälligen Steuerbescheide die noch nicht abgerechnet wurden.");
// event.setLink(link + "&task=Überfällig");
event.setLink(link + "&task=1200");
event.getData().setItemValue("value", computeSteuerbescheideSaldoDue());
event.getData().setItemValue("label", "EUR");
event.getData().setItemValue("description",
"Saldo aller überfälligen Steuerbescheide die noch nicht abgerechnet wurden.");
// event.getWorkitem().setItemValue("link", link + "&task=Überfällig");
event.getWorkitem().setItemValue("link", link + "&task=1200");
}
// Charts
if ("analytic.steuer.trend".equals(event.getKey())) {
event.setValue(accumulateSteuerbescheideByWeek());
event.setLabel("Zoll & EUST");
event.setDescription("Fälligkeiten nach KW");
event.getData().setItemValue("value", accumulateSteuerbescheideByWeek());
event.getData().setItemValue("label", "Zoll & EUST");
event.getData().setItemValue("description", "Fälligkeiten nach KW");
}
if ("analytic.steuer.trend.abteilung".equals(event.getKey())) {
event.setValue(accumulateSteuerbescheideAbteilungByWeek());
event.setLabel("Nach Abteilungen");
event.setDescription("Offene Salden nach KW pro Abteilung");
event.getData().setItemValue("value", accumulateSteuerbescheideAbteilungByWeek());
event.getData().setItemValue("label", "Nach Abteilungen");
event.getData().setItemValue("description", "Offene Salden nach KW pro Abteilung");
}
}

View file

@ -25,7 +25,7 @@ import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
import org.imixs.workflow.office.config.ConfigService;
import org.imixs.workflow.poi.POIFindReplaceAdapter;
import org.imixs.workflow.poi.POIUtil;
import org.imixs.workflow.poi.XSSFUtil;
import org.imixs.workflow.util.XMLParser;
import jakarta.inject.Inject;
@ -174,7 +174,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
int newColumns = (currencyList.size() - 1) * 2;
for (int i = 0; i < newColumns; i++) {
logger.info(".. add currency column...");
POIUtil.insertColumn(sheet, 6, 8 + i);
XSSFUtil.insertColumn(sheet, 6, 8 + i);
}
// Beschriftungen eintragen
@ -247,7 +247,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
// jetzt füge alle Rechnungen an.
int totalRowCount = invoices.size();
POIUtil.insertRows(sheet, "A11", totalRowCount - 0);
XSSFUtil.insertRows(sheet, "A11", totalRowCount - 0);
for (ItemCollection invoice : invoices) {
logger.fine("......add invoice " + invoice.getUniqueID());
@ -285,8 +285,8 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
// setze Summen Formeln
for (int column = 6; column < currencyList.size() * 2 + 6; column++) {
XSSFCell cell = sheet.getRow(totalRowCount + 11).getCell(column); // G11
String cellRefFrom = POIUtil.getCellReference(column, 10);
String cellRefTo = POIUtil.getCellReference(column, totalRowCount + 10);
String cellRefFrom = XSSFUtil.getCellReference(column, 10);
String cellRefTo = XSSFUtil.getCellReference(column, totalRowCount + 10);
String formula = "SUM(" + cellRefFrom + ":" + cellRefTo + ")";
cell.setCellFormula(formula);
}

View file

@ -0,0 +1,149 @@
/****************************************************************************
* Copyright (c) 2022-2025 Imixs Software Solutions GmbH and others.
* https://www.imixs.com
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0
*
* This Source Code may also be made available under the terms of the
* GNU General Public License, version 2 or later (GPL-2.0-or-later),
* which is available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
****************************************************************************/
package com.alexanderlogistics;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.imixs.workflow.engine.TextEvent;
import org.imixs.workflow.util.XMLParser;
import jakarta.ejb.Stateless;
import jakarta.enterprise.event.Observes;
/**
* The AGLTimestampAdapter replaces text fragments with a specific timestamp.
*
* The adapter parses a text for the tag `<timestamp />` and replaces the tag
* with the current system time.
* The output can be formatted with the attribute `format` adapting the Java
* Time Format.
* The timestamp can further be adjusted by days or minutes using the optional
* attributes `adjustDays` or `adjustMinutes`.
*
* NOTE: Can be removed with Imixs-Workflow versin 6.2.8
*
* @author rsoika
*
*/
@Stateless
public class AGLTimestampAdapter {
private static final Logger logger = Logger.getLogger(AGLTimestampAdapter.class.getName());
// Default format pattern used if no 'format' attribute is provided
private static final String DEFAULT_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
/**
* This method reacts on CDI events of the type TextEvent and parses a string
* for xml tag <timestamp>. Those tags will be replaced with the current
* system time.
*
*/
public void onEvent(@Observes TextEvent event) {
String text = event.getText();
boolean debug = logger.isLoggable(Level.FINE);
List<String> timestampTags = XMLParser.findTags(text, "timestamp");
// Replace each tag with the computed timestamp
for (String tag : timestampTags) {
String timestamp = computeTimestamp(tag);
if (debug) {
logger.log(Level.FINE, "replacing tag ''{0}'' with ''{1}''", new Object[] { tag, timestamp });
}
text = text.replace(tag, timestamp);
}
event.setText(text);
}
/**
* Computes the timestamp string for a given <timestamp .../> tag.
*
* Supports the optional attributes:
* - format: a java.time.format.DateTimeFormatter pattern
* - adjustDays: number of days to add (negative values subtract)
* - adjustMinutes: number of minutes to add (negative values subtract)
*
* @param tag - the full xml tag string, e.g. <timestamp format="dd.MM.yyyy" />
* @return the formatted timestamp
*/
/**
* Computes the timestamp string for a given <timestamp .../> tag.
*
* Supports the optional attributes:
* - format: a java.time.format.DateTimeFormatter pattern
* - adjustMonths: number of months to add (negative values subtract)
* - adjustDays: number of days to add (negative values subtract)
* - adjustMinutes: number of minutes to add (negative values subtract)
* - adjustSeconds: number of seconds to add (negative values subtract)
*
* @param tag - the full xml tag string, e.g. <timestamp format="dd.MM.yyyy" />
* @return the formatted timestamp
*/
private String computeTimestamp(String tag) {
LocalDateTime now = LocalDateTime.now();
now = applyAdjustment(now, tag, "adjustMonths", ChronoUnit.MONTHS);
now = applyAdjustment(now, tag, "adjustDays", ChronoUnit.DAYS);
now = applyAdjustment(now, tag, "adjustMinutes", ChronoUnit.MINUTES);
now = applyAdjustment(now, tag, "adjustSeconds", ChronoUnit.SECONDS);
// Resolve the format pattern, fallback to default if not provided or invalid
String format = XMLParser.findAttribute(tag, "format");
String pattern = (format != null && !format.isEmpty()) ? format : DEFAULT_FORMAT;
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return now.format(formatter);
} catch (IllegalArgumentException e) {
logger.log(Level.WARNING, "invalid format pattern ''{0}'' - using default format", pattern);
return now.format(DateTimeFormatter.ofPattern(DEFAULT_FORMAT));
}
}
/**
* Reads the given attribute from the tag and, if present, adjusts the
* given LocalDateTime by that amount using the specified ChronoUnit.
*
* @param dateTime - the date/time to adjust
* @param tag - the full xml tag string
* @param attributeName - the attribute name to look up (e.g. "adjustDays")
* @param unit - the ChronoUnit to apply the value with
* @return the adjusted LocalDateTime, or the unchanged input if the
* attribute is missing or invalid
*/
private LocalDateTime applyAdjustment(LocalDateTime dateTime, String tag, String attributeName, ChronoUnit unit) {
String value = XMLParser.findAttribute(tag, attributeName);
if (value != null && !value.isEmpty()) {
try {
long amount = Long.parseLong(value.trim());
return dateTime.plus(amount, unit);
} catch (NumberFormatException e) {
logger.log(Level.WARNING, "invalid {0} value ''{1}'' - ignoring",
new Object[] { attributeName, value });
}
}
return dateTime;
}
}

View file

@ -113,7 +113,10 @@ public class FTPConnector {
FTPClient ftpClient = null;
try {
logger.info("├── 🔜 uploading " + fileName + " to FTP server: " + ftpServer + " ...");
logger.info("│ ├── port=" + ftpPort.get().intValue());
logger.info("│ ├── working directory=" + ftpWorkingPath);
logger.info("│ ├── user=" + ftpUser.get());
// logger.info("│ ├── password=" + ftpPassword.get());
ftpClient = new FTPSClient("TLS", false);
ftpClient.setBufferSize(8192);
ftpClient.connect(ftpServer.get(), ftpPort.get().intValue());
@ -150,11 +153,17 @@ public class FTPConnector {
}
logger.info("│ └── ✓ ftp transfer completed.");
} catch (IOException e) {
} catch (IOException | PluginException e) {
// Log the real cause immediately, before the finally block runs -
// otherwise a cleanup failure could overwrite/hide this exception.
logger.warning("│ ├── ⚠️ FTP connection error: " + e.getMessage());
if (e instanceof PluginException) {
throw (PluginException) e;
}
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
"FTP file transfer failed: " + e.getMessage(), e);
} finally {
// Cleanup
// Cleanup - never let a cleanup failure mask the primary exception
try {
if (writer != null) {
writer.close();
@ -163,9 +172,10 @@ public class FTPConnector {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException e) {
} catch (IOException cleanupException) {
throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR,
"FTP file transfer failed during cleanup: " + e.getMessage(), e);
"FTP file transfer failed during cleanup: " + cleanupException.getMessage(),
cleanupException);
}
}
}

Some files were not shown because too many files have changed in this diff Show more