diff --git a/doc/FTP.md b/doc/FTP.md
index 13c4435..46356ce 100644
--- a/doc/FTP.md
+++ b/doc/FTP.md
@@ -96,4 +96,4 @@ Der Export erfolgt automatisch nach Empfang der Rechnung bzw. nach Prüfung der
Server: u248962.your-storagebox.de
Pfad: /office-alexander-logistics/cargosoft-br
Benutzername: u248962-sub13
- Passwort: ~AXh§#6n9XJPk~Z
+ Passwort: YjQ5u5Nzz535-eGR
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java
index 6e55c3c..a869ce8 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java
@@ -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);
}
}
}
diff --git a/reports/cargosoft/cargosoft-1.0.0-br.imixs-report b/reports/cargosoft/cargosoft-1.0.0-br.imixs-report
new file mode 100644
index 0000000..59b0591
--- /dev/null
+++ b/reports/cargosoft/cargosoft-1.0.0-br.imixs-report
@@ -0,0 +1,250 @@
+- 2024-02-02T13:13:38.991+01:00
- true
- 2026-07-27T15:14:40.666+02:00
- 806f9b2f-07ff-43d1-9b0d-1038804cc71c-1785158080668
- 806f9b2f-07ff-43d1-9b0d-1038804cc71c
- 2
- $uniqueid$workflowgroup$taskid$workflowsummaryinvoice.numberinvoice.dateinvoice.totalinvoice.currencycdtr.namecdtr.ibancdtr.bicdbtr.namedbtr.ibandbtr.bicpayment.typeinvoice.servicedate
- UTF-8
- Cargosoft Export - only the XSL Template is needed here!
- cargosoft
- ReportEntity
- <?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>
-
+ /office-alexander-logistics/reports/cargosoft/cargosoft-1.0.6.xsl
\ No newline at end of file
diff --git a/reports/cargosoft/cargosoft-1.0.0-br.xsl b/reports/cargosoft/cargosoft-1.0.0-br.xsl
new file mode 100644
index 0000000..784363b
--- /dev/null
+++ b/reports/cargosoft/cargosoft-1.0.0-br.xsl
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+
+
+
+
+ Imixs-Office-Workflow
+ Cargosoft
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 008
+
+
+
+
+
+
+
+
+
+
+
+
+ CREDIT
+
+
+ INVOICE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+ Imixs-Office-Workflow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/sepa/sepa-br.xlsx b/templates/sepa/sepa-br.xlsx
new file mode 100644
index 0000000..0b8a0d7
Binary files /dev/null and b/templates/sepa/sepa-br.xlsx differ