added qr-code to invoice
This commit is contained in:
parent
e09e25766a
commit
5f20bc458b
4 changed files with 413 additions and 127 deletions
|
|
@ -7,7 +7,6 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
|
@ -21,7 +20,6 @@ import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
|
|||
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
|
||||
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
|
||||
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
|
||||
import org.imixs.archive.core.SnapshotService;
|
||||
import org.imixs.einvoice.EInvoiceFormatException;
|
||||
import org.imixs.einvoice.EInvoiceModel;
|
||||
import org.imixs.einvoice.EInvoiceModelFactory;
|
||||
|
|
@ -34,11 +32,11 @@ 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 com.alexanderlogistics.BusinessPartnerService;
|
||||
import com.alexanderlogistics.InvoiceUtil;
|
||||
import com.alexanderlogistics.ksef.api.KSeFAPIService;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
|
|
@ -80,9 +78,6 @@ import jakarta.inject.Inject;
|
|||
*/
|
||||
public class EInvoiceAdapter 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 LINE_ITEMS_PROPERTY = "invoice.items";
|
||||
private static Logger logger = Logger.getLogger(EInvoiceAdapter.class.getName());
|
||||
|
||||
|
|
@ -97,10 +92,10 @@ public class EInvoiceAdapter implements SignalAdapter {
|
|||
DocumentService documentService;
|
||||
|
||||
@Inject
|
||||
SnapshotService snapshotService;
|
||||
BusinessPartnerService businessPartnerService;
|
||||
|
||||
@Inject
|
||||
BusinessPartnerService businessPartnerService;
|
||||
KSeFAPIService kSeFAPIService;
|
||||
|
||||
/**
|
||||
* This method
|
||||
|
|
@ -117,14 +112,14 @@ public class EInvoiceAdapter implements SignalAdapter {
|
|||
workitem,
|
||||
false);
|
||||
if (eInvoiceConfig == null || !eInvoiceConfig.hasItem("create")) {
|
||||
throw new PluginException(EInvoiceAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||
throw new PluginException(EInvoiceAdapter.class.getSimpleName(), KSeFAPIService.CONFIG_ERROR,
|
||||
"missing e-invoice configuration in model event - please check model configuration");
|
||||
}
|
||||
ItemCollection createDefinition = XMLParser.parseItemStructure(eInvoiceConfig.getItemValueString("CREATE"));
|
||||
try {
|
||||
// Load the e-invoice template....
|
||||
FileData xmlFileData = loadXMLTemplate(workitem, createDefinition);
|
||||
FileData pdfFileData = loadPDF(workitem);
|
||||
FileData xmlFileData = kSeFAPIService.loadXMLTemplate(workitem, createDefinition);
|
||||
FileData pdfFileData = kSeFAPIService.loadPDF(workitem);
|
||||
|
||||
logger.info("│ ├── Source File: " + pdfFileData.getName());
|
||||
|
||||
|
|
@ -148,47 +143,50 @@ public class EInvoiceAdapter implements SignalAdapter {
|
|||
return workitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper method tries to find the pdf file matching the item
|
||||
* 'cargosoft.import.filename'. If not found the method returns the first .pdf
|
||||
* file form the list of attachments. The method returns null if no pdf file
|
||||
* exits
|
||||
*
|
||||
* @param workitem
|
||||
* @return the pdf FileData object
|
||||
* @throws PluginException if not pdf file was found
|
||||
*/
|
||||
private FileData loadPDF(ItemCollection workitem) throws PluginException {
|
||||
FileData pdfFileData = null;
|
||||
String cargosoftFileName = workitem.getItemValueString("cargosoft.import.filename");
|
||||
if (!cargosoftFileName.isEmpty()) {
|
||||
cargosoftFileName = cargosoftFileName.replace(".xml", ".pdf");
|
||||
// /**
|
||||
// * This helper method tries to find the pdf file matching the item
|
||||
// * 'cargosoft.import.filename'. If not found the method returns the first .pdf
|
||||
// * file form the list of attachments. The method returns null if no pdf file
|
||||
// * exits
|
||||
// *
|
||||
// * @param workitem
|
||||
// * @return the pdf FileData object
|
||||
// * @throws PluginException if not pdf file was found
|
||||
// */
|
||||
// private FileData loadPDF(ItemCollection workitem) throws PluginException {
|
||||
// FileData pdfFileData = null;
|
||||
// String cargosoftFileName =
|
||||
// workitem.getItemValueString("cargosoft.import.filename");
|
||||
// if (!cargosoftFileName.isEmpty()) {
|
||||
// cargosoftFileName = cargosoftFileName.replace(".xml", ".pdf");
|
||||
|
||||
// try to load filedata....
|
||||
pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), cargosoftFileName);
|
||||
// // try to load filedata....
|
||||
// pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(),
|
||||
// cargosoftFileName);
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
if (pdfFileData == null) {
|
||||
// take first pdf file available
|
||||
List<String> fileNames = workitem.getFileNames();
|
||||
for (String filename : fileNames) {
|
||||
// if (pdfFileData == null) {
|
||||
// // take first pdf file available
|
||||
// List<String> fileNames = workitem.getFileNames();
|
||||
// for (String filename : fileNames) {
|
||||
|
||||
if (filename.toLowerCase().endsWith(".pdf")) {
|
||||
pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (filename.toLowerCase().endsWith(".pdf")) {
|
||||
// pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(),
|
||||
// filename);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (pdfFileData == null) {
|
||||
throw new PluginException(EInvoiceAdapter.class.getSimpleName(),
|
||||
DOCUMENT_ERROR,
|
||||
"DOCUMENT_ERROR: no pdf file found!");
|
||||
}
|
||||
return pdfFileData;
|
||||
// if (pdfFileData == null) {
|
||||
// throw new PluginException(EInvoiceAdapter.class.getSimpleName(),
|
||||
// DOCUMENT_ERROR,
|
||||
// "DOCUMENT_ERROR: no pdf file found!");
|
||||
// }
|
||||
// return pdfFileData;
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
private FileData embeddXML(FileData pdfFileData, FileData xmlFileData) throws PluginException {
|
||||
try {
|
||||
|
|
@ -236,7 +234,7 @@ public class EInvoiceAdapter implements SignalAdapter {
|
|||
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
throw new PluginException(EInvoiceAdapter.class.getSimpleName(), CONFIG_ERROR,
|
||||
throw new PluginException(EInvoiceAdapter.class.getSimpleName(), KSeFAPIService.CONFIG_ERROR,
|
||||
"Failed to generate e-invoice: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -298,7 +296,7 @@ public class EInvoiceAdapter implements SignalAdapter {
|
|||
fileDataXMLTemplate.setContent(model.getContent());
|
||||
|
||||
} catch (FileNotFoundException | EInvoiceFormatException | TransformerException e) {
|
||||
throw new PluginException(this.getClass().getName(), DOCUMENT_ERROR, e.getMessage(), e);
|
||||
throw new PluginException(this.getClass().getName(), KSeFAPIService.DOCUMENT_ERROR, e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -312,12 +310,12 @@ public class EInvoiceAdapter implements SignalAdapter {
|
|||
*/
|
||||
public TradeParty buildAddress(String partnerID, String type) throws PluginException {
|
||||
if (partnerID == null || partnerID.isEmpty()) {
|
||||
throw new PluginException(this.getClass().getName(), DOCUMENT_ERROR, "Missing partnerID");
|
||||
throw new PluginException(this.getClass().getName(), KSeFAPIService.DOCUMENT_ERROR, "Missing partnerID");
|
||||
}
|
||||
|
||||
ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(partnerID);
|
||||
if (businessPartner == null) {
|
||||
throw new PluginException(this.getClass().getName(), DOCUMENT_ERROR,
|
||||
throw new PluginException(this.getClass().getName(), KSeFAPIService.DOCUMENT_ERROR,
|
||||
"Business Partner ID '" + partnerID + "' does not exist");
|
||||
}
|
||||
TradeParty tradeParty = new TradeParty(type);
|
||||
|
|
@ -352,80 +350,4 @@ public class EInvoiceAdapter implements SignalAdapter {
|
|||
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 = "factur-x.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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.alexanderlogistics.einvoice;
|
||||
|
||||
import org.imixs.archive.core.SnapshotService;
|
||||
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 com.alexanderlogistics.BusinessPartnerService;
|
||||
import com.alexanderlogistics.ksef.api.KSeFAPIService;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @version 1.0
|
||||
* @author rsoika
|
||||
*/
|
||||
public class QRTest implements SignalAdapter {
|
||||
|
||||
@Inject
|
||||
WorkflowService workflowService;
|
||||
|
||||
@Inject
|
||||
DocumentService documentService;
|
||||
|
||||
@Inject
|
||||
SnapshotService snapshotService;
|
||||
|
||||
@Inject
|
||||
BusinessPartnerService businessPartnerService;
|
||||
|
||||
@Inject
|
||||
KSeFAPIService kSeFAPIService;
|
||||
|
||||
/**
|
||||
* This method
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
@Override
|
||||
public ItemCollection execute(ItemCollection workitem, ItemCollection event)
|
||||
throws AdapterException, PluginException {
|
||||
|
||||
kSeFAPIService.embedQRCode(workitem);
|
||||
return workitem;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -23,11 +24,18 @@ import javax.crypto.NoSuchPaddingException;
|
|||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.imixs.archive.core.SnapshotService;
|
||||
import org.imixs.workflow.FileData;
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
import org.imixs.workflow.engine.DocumentService;
|
||||
import org.imixs.workflow.engine.WorkflowService;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
import org.imixs.workflow.exceptions.QueryException;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.WriterException;
|
||||
|
|
@ -64,6 +72,9 @@ public class KSeFAPIService {
|
|||
private static Logger logger = Logger.getLogger(KSeFAPIService.class.getName());
|
||||
|
||||
public static final String ERROR_API = "API_ERROR";
|
||||
public static final String DOCUMENT_ERROR = "DOCUMENT_ERROR";
|
||||
public static final String CONFIG_ERROR = "CONFIG_ERROR";
|
||||
final String TYPE_TEXTBLOCK = "textblock";
|
||||
|
||||
@Inject
|
||||
KSeFAuthManager kseFAuthManager;
|
||||
|
|
@ -71,6 +82,9 @@ public class KSeFAPIService {
|
|||
@Inject
|
||||
DocumentService documentService;
|
||||
|
||||
@Inject
|
||||
WorkflowService workflowService;
|
||||
|
||||
@Inject
|
||||
SnapshotService snapshotService;
|
||||
|
||||
|
|
@ -249,6 +263,9 @@ public class KSeFAPIService {
|
|||
|
||||
// store QR Code
|
||||
generateQRCode(workitem);
|
||||
|
||||
// print QR Code to pdf
|
||||
embedQRCode(workitem);
|
||||
}
|
||||
|
||||
} catch (IOException | NoSuchAlgorithmException | InterruptedException e) {
|
||||
|
|
@ -453,6 +470,88 @@ public class KSeFAPIService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper method prints the QR Code on the AGL Invoice document
|
||||
*
|
||||
* @param workitem
|
||||
* @throws PluginException
|
||||
*/
|
||||
public void embedQRCode(ItemCollection workitem) {
|
||||
|
||||
try {
|
||||
FileData pdfFileData = this.loadPDF(workitem);
|
||||
|
||||
String ksefRefNumber = workitem.getItemValueString("ksef.referenceNumber");
|
||||
FileData qrCodeFileData = workitem.getFileData(ksefRefNumber + ".png");
|
||||
if (qrCodeFileData.getContent().length == 0) {
|
||||
qrCodeFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), ksefRefNumber + ".png");
|
||||
}
|
||||
|
||||
// now we have the QR Code (qrCodeFileData) and the PDF (pdfFileData)
|
||||
PDDocument document = PDDocument.load(pdfFileData.getContent());
|
||||
|
||||
logger.info("pdf file loaded, embed qrcode...");
|
||||
// place thee PNG on the first page 10x10 cm from left upper corner
|
||||
// ....
|
||||
PDPage page = document.getPage(0);
|
||||
PDImageXObject pdImage = PDImageXObject.createFromByteArray(document, qrCodeFileData.getContent(),
|
||||
pdfFileData.getName());
|
||||
// PDPageContentStream contentStream = new PDPageContentStream(document, page);
|
||||
|
||||
PDPageContentStream contentStream = new PDPageContentStream(
|
||||
document,
|
||||
page,
|
||||
PDPageContentStream.AppendMode.APPEND, // Append statt Overwrite
|
||||
true, // compress
|
||||
true // resetContext - wichtig für konsistente Grafik-Zustände
|
||||
);
|
||||
|
||||
// Mit Größenangabe (Breite und Höhe in Points):
|
||||
// QR-Code zeichnen
|
||||
// Seitenhöhe auslesen
|
||||
float pageHeight = page.getMediaBox().getHeight();
|
||||
// Position von OBEN berechnen (z.B. 50 Points vom oberen Rand)
|
||||
float marginFromTop = 230;
|
||||
float imageWidth = 50;
|
||||
float imageHeight = 50;
|
||||
float imageX = 350;
|
||||
float imageY = pageHeight - marginFromTop - imageHeight; // Von oben berechnet!
|
||||
|
||||
contentStream.drawImage(pdImage, imageX, imageY, imageWidth, imageHeight);
|
||||
|
||||
// Text darunter schreiben
|
||||
String text = "KSeF-No.: " + workitem.getItemValueString("ksef.number");
|
||||
float fontSize = 7;
|
||||
PDType1Font font = PDType1Font.COURIER;
|
||||
float textX = imageX + 5;
|
||||
float textY = imageY - 5; // 10 Points unter dem Bild
|
||||
contentStream.beginText();
|
||||
contentStream.setFont(font, fontSize);
|
||||
contentStream.newLineAtOffset(textX, textY);
|
||||
contentStream.showText(text);
|
||||
contentStream.endText();
|
||||
|
||||
contentStream.close();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
document.save(baos);
|
||||
byte[] eInvoiceData = baos.toByteArray();
|
||||
document.close();
|
||||
baos.close();
|
||||
|
||||
pdfFileData.setContent(eInvoiceData);
|
||||
|
||||
// finally update the pdf file
|
||||
workitem.removeFile(pdfFileData.getName());
|
||||
// set new pdf file...
|
||||
workitem.addFileData(pdfFileData);
|
||||
|
||||
} catch (IOException | PluginException e) {
|
||||
logger.warning("Failed to embed QR Code on PDF file: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt invoice XML with the session encryption keys
|
||||
*
|
||||
|
|
@ -505,4 +604,117 @@ public class KSeFAPIService {
|
|||
return Base64.getEncoder().encodeToString(hashBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper method tries to find the pdf file matching the item
|
||||
* 'cargosoft.import.filename'. If not found the method returns the first .pdf
|
||||
* file form the list of attachments. The method returns null if no pdf file
|
||||
* exits
|
||||
*
|
||||
* @param workitem
|
||||
* @return the pdf FileData object
|
||||
* @throws PluginException if not pdf file was found
|
||||
*/
|
||||
public FileData loadPDF(ItemCollection workitem) throws PluginException {
|
||||
FileData pdfFileData = null;
|
||||
String cargosoftFileName = workitem.getItemValueString("cargosoft.import.filename");
|
||||
if (!cargosoftFileName.isEmpty()) {
|
||||
cargosoftFileName = cargosoftFileName.replace(".xml", ".pdf");
|
||||
|
||||
// try to load filedata....
|
||||
pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), cargosoftFileName);
|
||||
|
||||
}
|
||||
|
||||
if (pdfFileData == null) {
|
||||
// take first pdf file available
|
||||
List<String> fileNames = workitem.getFileNames();
|
||||
for (String filename : fileNames) {
|
||||
|
||||
if (filename.toLowerCase().endsWith(".pdf")) {
|
||||
pdfFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pdfFileData == null) {
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(),
|
||||
DOCUMENT_ERROR,
|
||||
"DOCUMENT_ERROR: no pdf file found!");
|
||||
}
|
||||
return pdfFileData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method loads a text-block for a specified ref and appends the named
|
||||
* fileData object of this document.
|
||||
*
|
||||
* @param document
|
||||
* @throws PluginException
|
||||
*/
|
||||
|
||||
public FileData loadXMLTemplate(ItemCollection workitem, ItemCollection config)
|
||||
throws PluginException {
|
||||
|
||||
String textblock = config.getItemValueString("textblock");
|
||||
String template = config.getItemValueString("template");
|
||||
String sourceName = config.getItemValueString("source");
|
||||
|
||||
String targetName = "factur-x.xml";
|
||||
|
||||
// adapt text....
|
||||
sourceName = workflowService.adaptText(sourceName, workitem);
|
||||
|
||||
if ((template == null || template.isEmpty()) || (textblock == null || textblock.isEmpty())) {
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(),
|
||||
KSeFAPIService.CONFIG_ERROR,
|
||||
"invalid e-invoice configuration in model event - textblock/template reference not defined!");
|
||||
}
|
||||
|
||||
// load the text block
|
||||
FileData fileData = this.loadTextBlockFileData(textblock, template);
|
||||
|
||||
// do we found the document?
|
||||
if (fileData == null) {
|
||||
throw new PluginException(KSeFAPIService.class.getSimpleName(),
|
||||
KSeFAPIService.CONFIG_ERROR,
|
||||
"invalid e-invoice configuration in model event - textblock/template: " + textblock + "/" + template
|
||||
+ " not found!");
|
||||
}
|
||||
fileData.setName(targetName);
|
||||
|
||||
return fileData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ th { font-weight: bold;}
|
|||
<bpmn2:flowNodeRef>ExclusiveGateway_3</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>dataObject_V0KVQg</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>event_w96sOg</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>event_xxUDcA</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
</bpmn2:laneSet>
|
||||
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_5000-20" imixs:activityid="50" name="[Due date]">
|
||||
|
|
@ -340,6 +341,19 @@ Bei Fragen wenden Sie sich bitte an info@imixs.com
|
|||
<imixs-form-section label="Invoice positions" path="alexander/section_datevbuchung" />
|
||||
<imixs-form-section label="Payment" path="alexander/section_payments" />
|
||||
<imixs-form-section label="Dunning" path="alexander/section_dunnings" />
|
||||
|
||||
|
||||
<imixs-form-section columns="1" label="KSeF">
|
||||
<item name="ksef.encryptedinvoicehash" type="text" label="Encrypted Invoice Hash:" readonly="true" />
|
||||
<item name="ksef.invoicehash" type="text" label="Invoice Hash:" readonly="true" />
|
||||
<item name="ksef.number" type="text" label="KSeF Number:" readonly="true" />
|
||||
<item name="ksef.referencenumber" type="text" label="Ref.No.:" readonly="true" />
|
||||
<item name="ksef.status.description" type="text" label="Status:" readonly="true" />
|
||||
<item name="ksef.upo.downloadurl" type="text" label="Download URL:" readonly="true" />
|
||||
<item name="ksef.upo.referencenumber" type="text" label="UPO Ref.No.:" readonly="true" />
|
||||
<item name="ksef.verificationurl" type="text" label="Verification URL:" readonly="true" />
|
||||
</imixs-form-section>
|
||||
|
||||
</imixs-form>]]></bpmn2:documentation>
|
||||
<bpmn2:dataState id="DataState_1"/>
|
||||
</bpmn2:dataObject>
|
||||
|
|
@ -496,6 +510,7 @@ Bei Fragen wenden Sie sich bitte an info@imixs.com
|
|||
<bpmn2:documentation id="Documentation_9"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation>
|
||||
<bpmn2:incoming>SequenceFlow_27</bpmn2:incoming>
|
||||
<bpmn2:incoming>sequenceFlow_EZX5kQ</bpmn2:incoming>
|
||||
<bpmn2:incoming>sequenceFlow_seshBg</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_18</bpmn2:outgoing>
|
||||
<bpmn2:outgoing>SequenceFlow_34</bpmn2:outgoing>
|
||||
<bpmn2:incoming>sequenceFlow_zhcE7Q</bpmn2:incoming>
|
||||
|
|
@ -2428,7 +2443,7 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
|
|||
<bpmn2:association id="association_PwhTLg" sourceRef="textAnnotation_zVr90Q" targetRef="event_NIn1DQ">
|
||||
<bpmn2:documentation id="documentation_3RHL2w"/>
|
||||
</bpmn2:association>
|
||||
<bpmn2:intermediateThrowEvent id="event_rTm4Aw" name="KSEF">
|
||||
<bpmn2:intermediateThrowEvent id="event_rTm4Aw" name="EINVOICE">
|
||||
<bpmn2:incoming>sequenceFlow_bRxzKQ</bpmn2:incoming>
|
||||
<bpmn2:linkEventDefinition id="linkEventDefinition_XpOKjQ" name="Link Event Definition 5"/>
|
||||
<bpmn2:documentation id="documentation_jDLGbA"/>
|
||||
|
|
@ -2571,6 +2586,79 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
|
|||
<bpmn2:association id="association_XEg2bw" sourceRef="task_aZVPjw" targetRef="textAnnotation_CARutw">
|
||||
<bpmn2:documentation id="documentation_LZEbVQ"/>
|
||||
</bpmn2:association>
|
||||
<bpmn2:intermediateCatchEvent id="event_xxUDcA" imixs:activityid="10" name="Save">
|
||||
<bpmn2:extensionElements>
|
||||
<imixs:item name="keylogtimeformat" type="xs:string">
|
||||
<imixs:value><![CDATA[2]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyarchive" type="xs:string">
|
||||
<imixs:value><![CDATA[0]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtmailsubject" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyaccessmode" type="xs:string">
|
||||
<imixs:value><![CDATA[0]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyscheduledactivity" type="xs:string">
|
||||
<imixs:value><![CDATA[0]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="rtfmailbody" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyversion" type="xs:string">
|
||||
<imixs:value><![CDATA[0]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyaddwritefields" type="xs:string">
|
||||
<imixs:value><![CDATA[$creator]]></imixs:value>
|
||||
<imixs:value><![CDATA[$editor]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.manager]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.team]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="numnextactivityid" type="xs:int">
|
||||
<imixs:value><![CDATA[0]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyfollowup" type="xs:string">
|
||||
<imixs:value><![CDATA[2]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keypublicresult" type="xs:string">
|
||||
<imixs:value><![CDATA[1]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keylogdateformat" type="xs:string">
|
||||
<imixs:value><![CDATA[2]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyownershipfields" type="xs:string">
|
||||
<imixs:value><![CDATA[$editor]]></imixs:value>
|
||||
<imixs:value><![CDATA[$creator]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="numnextid" type="xs:int">
|
||||
<imixs:value><![CDATA[5000]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtnextprocesstree" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtactivityresult" type="xs:string">
|
||||
<imixs:value><![CDATA[<item name="comment" ignore="true"/>]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtname" type="xs:string">
|
||||
<imixs:value><![CDATA[Speichern]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyownershipmode" type="xs:string">
|
||||
<imixs:value><![CDATA[0]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="rtfresultlog" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyupdateacl" type="xs:boolean">
|
||||
<imixs:value>false</imixs:value>
|
||||
</imixs:item>
|
||||
</bpmn2:extensionElements>
|
||||
<bpmn2:documentation id="documentation_CVDzIA"><![CDATA[Zwischenspeichern]]></bpmn2:documentation>
|
||||
<bpmn2:outgoing>sequenceFlow_seshBg</bpmn2:outgoing>
|
||||
</bpmn2:intermediateCatchEvent>
|
||||
<bpmn2:sequenceFlow id="sequenceFlow_seshBg" sourceRef="event_xxUDcA" targetRef="Task_1">
|
||||
<bpmn2:documentation id="documentation_wxQsPA"/>
|
||||
</bpmn2:sequenceFlow>
|
||||
</bpmn2:process>
|
||||
<bpmn2:process id="process_2" name="Default Process" processType="Public">
|
||||
<bpmn2:documentation id="documentation_J67Rkw"/>
|
||||
|
|
@ -2583,6 +2671,7 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
|
|||
<bpmn2:signal id="signal_9" name="com.alexanderlogistics.einvoice.EInvoiceAdapter"/>
|
||||
<bpmn2:signal id="signal_10" name="com.alexanderlogistics.einvoice.KSeFAdapter"/>
|
||||
<bpmn2:signal id="signal_11" name="com.alexanderlogistics.einvoice.KSeFAPIAdapter"/>
|
||||
<bpmn2:signal id="signal_12" name="com.alexanderlogistics.einvoice.QRTest"/>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane bpmnElement="Collaboration_1" id="BPMNPlane_Process_1">
|
||||
<bpmndi:BPMNShape bpmnElement="Participant_1" id="BPMNShape_Participant_1" isHorizontal="true">
|
||||
|
|
@ -2966,6 +3055,12 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
|
|||
<bpmndi:BPMNShape bpmnElement="textAnnotation_CARutw" id="BPMNShape_x4G0Eg">
|
||||
<dc:Bounds height="109.0" width="294.0" x="310.0" y="890.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="event_xxUDcA" id="BPMNShape_B0zMZw">
|
||||
<dc:Bounds height="36.0" width="36.0" x="1421.0" y="1533.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_yQj5fA">
|
||||
<dc:Bounds height="20.0" width="100.0" x="1389.0" y="1572.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_33" id="BPMNEdge_SequenceFlow_34" sourceElement="BPMNShape_ExclusiveGateway_1">
|
||||
<di:waypoint x="910.0" y="835.0"/>
|
||||
<di:waypoint x="1130.0" y="835.0"/>
|
||||
|
|
@ -3338,6 +3433,12 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
|
|||
<di:waypoint x="457.0" y="875.0"/>
|
||||
<di:waypoint x="457.0" y="890.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_seshBg" id="BPMNEdge_yhILiw" sourceElement="BPMNShape_B0zMZw" targetElement="BPMNShape_Task_3">
|
||||
<di:waypoint x="1421.0" y="1551.0"/>
|
||||
<di:waypoint x="1331.0" y="1551.0"/>
|
||||
<di:waypoint x="1331.0" y="1375.0"/>
|
||||
<di:waypoint x="1240.0" y="1375.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
|
||||
<dc:Font name="arial" size="9.0"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue