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:00true2026-07-27T15:14:40.666+02:00806f9b2f-07ff-43d1-9b0d-1038804cc71c-1785158080668806f9b2f-07ff-43d1-9b0d-1038804cc71c2$uniqueid$workflowgroup$taskid$workflowsummaryinvoice.numberinvoice.dateinvoice.totalinvoice.currencycdtr.namecdtr.ibancdtr.bicdbtr.namedbtr.ibandbtr.bicpayment.typeinvoice.servicedateUTF-8Cargosoft Export - only the XSL Template is needed here!cargosoftReportEntity<?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