neuer AGLAIInvoiceAdapter für auflösung von space.ref

This commit is contained in:
Ralph Soika 2026-08-19 10:18:36 +02:00
parent 44df91da9d
commit f942231066
7 changed files with 5285 additions and 5 deletions

View file

@ -1,5 +1,16 @@
# Versionen # Versionen
## 1.4.0 (Development)
- neuer AGLAIInvoiceAdapter
der Adapter `AGLAIInvoiceAdapter` muss künftig in das Import Event der Rechnungseingangs Modelle. Dieser Adapter Findet den Space und den Mandanten.
Neue Modelle:
- AMS
- rechnungseingang-ams-1.1.0.bpmn
## 1.3.6 (Development) ## 1.3.6 (Development)
**KSeF Produktiname II.** **KSeF Produktiname II.**

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", invoice.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

@ -129,10 +129,11 @@ public class MahnlaufService {
* @param workitem * @param workitem
* @param spacePosMappings * @param spacePosMappings
*/ */
public void mapInvoiceTextToSpace(ItemCollection workitem, Map<String, List<String>> spacePosMappings) { public void mapInvoiceTextToSpace(ItemCollection workitem, Map<String, List<String>> spacePosMappings,
String positionNumber) {
// Jezt noch das Space mapping // Jezt noch das Space mapping
// dazu kucken wir in alle spaces den config wert 'pos.mapping' // dazu kucken wir in alle spaces den config wert 'pos.mapping'
String text = workitem.getItemValueString("invoice.text"); String text = positionNumber; // workitem.getItemValueString("invoice.text");
if (!text.isEmpty()) { if (!text.isEmpty()) {
boolean found = false; boolean found = false;
for (Map.Entry<String, List<String>> entry : spacePosMappings.entrySet()) { for (Map.Entry<String, List<String>> entry : spacePosMappings.entrySet()) {

View file

@ -428,7 +428,8 @@ public class CargosoftXMLEAkteImportService {
readXMLRows(doc, workitem); readXMLRows(doc, workitem);
// Jetzt noch das Space mapping // Jetzt noch das Space mapping
workitem.setItemValue("invoice.text", workitem.getItemValueString("invoice.positions")); workitem.setItemValue("invoice.text", workitem.getItemValueString("invoice.positions"));
mahnlaufService.mapInvoiceTextToSpace(workitem, spacePosMappings); mahnlaufService.mapInvoiceTextToSpace(workitem, spacePosMappings,
workitem.getItemValueString("invoice.positions"));
// Finally we attache the pdf file and the XML content to the workitem. // Finally we attache the pdf file and the XML content to the workitem.
attacheFiles(doc, workitem); attacheFiles(doc, workitem);

View file

@ -482,7 +482,8 @@ public class CargosoftXMLInvoiceImportService {
resolveATCNumbers(doc, workitem); resolveATCNumbers(doc, workitem);
// Jetzt noch das Space mapping // Jetzt noch das Space mapping
mahnlaufService.mapInvoiceTextToSpace(workitem, spacePosMappings); mahnlaufService.mapInvoiceTextToSpace(workitem, spacePosMappings,
workitem.getItemValueString("invoice.text"));
// Rückstellungen ignorieren // Rückstellungen ignorieren
if (isRueckStellung(workitem)) { if (isRueckStellung(workitem)) {

View file

@ -36,7 +36,7 @@ import jakarta.inject.Named;
/** /**
* Der ZohoController ist für das Admin Interface um Access Tokens zu erzeugen. * Der ZohoController ist für das Admin Interface um Access Tokens zu erzeugen.
* *
* @see admin/zoho.xhml * @see zoho.xhml
* *
* @author rsoika * @author rsoika
* *

File diff suppressed because it is too large Load diff