update cargosoft export

This commit is contained in:
Ralph Soika 2022-09-08 17:12:35 +02:00
parent a1e44d70c3
commit 406f0a415b
6 changed files with 404 additions and 268 deletions

View file

@ -0,0 +1,81 @@
package com.alexanderlogistics.datev;
/*******************************************************************************
* 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
*
*******************************************************************************/
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import org.imixs.workflow.datev.imports.DatevImportScheduler;
import org.imixs.workflow.engine.scheduler.SchedulerController;
/**
* The DatevController is used to configure the DatevScheduler. This service is
* used to generate datev export workitems.
* <p>
* The Controller creates a configuration entity "type=configuration;
* txtname=datev".
* <p>
* The following config items are defined:
*
* The following config items are defined:
*
* <pre>
* _model_version = model version for the SEPA export
* _initial_task = inital task ID
* </pre>
*
*
* @author rsoika
*
*/
@Named
@RequestScoped
public class CargosoftExportController extends SchedulerController {
public static final String CARGOSOFT_EXPORT_CONFIGURATION = "CARGOSOFT_EXPORT_CONFIGURATION";
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(CargosoftExportController.class.getName());
@Override
public String getName() {
return CARGOSOFT_EXPORT_CONFIGURATION;
}
/**
* Returns the sepa scheduler class name. This name depends on the _export_type.
*
* There are two export interfaces available - csv and XML
*
*/
@Override
public String getSchedulerClass() {
String schedulerClass = CargosoftExportScheduler.class.getName();
logger.finest("...... scheduler: " + schedulerClass);
return schedulerClass;
}
}

View file

@ -0,0 +1,162 @@
/*******************************************************************************
* Imixs Workflow Technology
* Copyright (C) 2001, 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 com.alexanderlogistics.datev;
import java.io.ByteArrayOutputStream;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.logging.Logger;
import javax.ejb.EJB;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.engine.ModelService;
import org.imixs.workflow.engine.ReportService;
import org.imixs.workflow.engine.WorkflowService;
import org.imixs.workflow.engine.scheduler.Scheduler;
import org.imixs.workflow.engine.scheduler.SchedulerException;
import org.imixs.workflow.engine.scheduler.SchedulerService;
import org.imixs.workflow.exceptions.QueryException;
/**
* The CargosoftExportScheduler exports a csv file with kreditor data
* <p>
* The class implements the interface
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
* combination with the Imxis-Workflow Scheduler Service.
*
* @see SchedulerService
* @author rsoika
*
*/
public class CargosoftExportScheduler implements Scheduler {
public static final int MAX_COUNT = 999;
public static DateFormat dateFormat = new SimpleDateFormat("ddMMyyyy");
public static DecimalFormat decimalFormat = new DecimalFormat("0.00");
public static DecimalFormat rateFormat = new DecimalFormat("0.000000");
@EJB
DocumentService documentService;
@EJB
WorkflowService workflowService;
@EJB
ModelService modelService;
@EJB
ReportService reportService;
private static Logger logger = Logger.getLogger(CargosoftExportScheduler.class.getName());
/**
* This is the method which processes the timeout event depending on the running
* timer settings.
*
*
*
* @param timer
* @throws QueryException
*/
public ItemCollection run(ItemCollection configuration) throws SchedulerException {
ByteArrayOutputStream outputStream = null;
List<ItemCollection> invoices = null;
String reportName = "";
ItemCollection datevExport = null;
int maxCount = configuration.getItemValueInteger("_maxcount");
if (maxCount == 0) {
maxCount = -1;
}
logger.info("....export to Cargosoft...");
// $taskID<5900
String sQuery = "(type:workitem AND $modelversion:rechnungsausgang* AND $taskid:[5000 TO 5899])";
try {
// find the textblock...
invoices = documentService.find(sQuery, 9999, 0);
} catch (QueryException e) {
logger.warning("failed to search invoices by query: " + e.getMessage());
}
if (invoices != null && invoices.size() > 0) {
// File csvOutputFile = new File(CSV_FILE_NAME);
for (ItemCollection doc : invoices) {
String line = "";
line = line + doc.getItemValueString("dbtr.number") + ";";
line = line + "\"" + doc.getItemValueString("dbtr.name") + "\";";
line = line + "\"" + doc.getItemValueString("invoice.number") + "\";";
line = line + dateFormat.format(doc.getItemValueDate("invoice.date")) + ";";
line = line + dateFormat.format(doc.getItemValueDate("invoice.duedate")) + ";";
// Betrag soll; Betrag Haben;
double betrag = doc.getItemValueDouble("invoice.total");
if (betrag >= 0) {
// Soll
line = line + decimalFormat.format(betrag) + ";0,00;";
} else {
// Haben
line = line + "0,00;" + decimalFormat.format(Math.abs(betrag)) + ";";
}
// Saldo; S/H Saldo
betrag = doc.getItemValueDouble("invoice.saldo");
if (betrag >= 0) {
// Soll
line = line + decimalFormat.format(betrag) + ";S;";
} else {
// Haben
line = line + decimalFormat.format(Math.abs(betrag)) + ";H;";
}
// WKZ
String wkz = doc.getItemValueString("invoice.currency");
if (!"EUR".equals(wkz)) {
line = line + wkz + ";" + rateFormat.format(doc.getItemValueDouble("invoice.rate")) + ";"
+ decimalFormat.format(doc.getItemValueDouble("invoice.base.amount")) + ";";
} else {
line = line + ";0,000000;0,00;";
}
//77 ;
int i=77;
while(i>0) {
line = line + ";";
i--;
}
logger.info(line);
}
}
return configuration;
}
}

View file

@ -152,7 +152,9 @@ public class DatevCargosoftImportAdapter implements SignalAdapter {
String paymentTerm= DatevImportAdapter.csvVal(header1List[31]);
String waehrung = DatevImportAdapter.csvVal(header1List[2]);
// kurse
double kurs=parseBetrag(DatevImportAdapter.csvVal(header1List[3]));
double basisumsatz= parseBetrag(DatevImportAdapter.csvVal(header1List[4]));
// Skip Eingangsrechnungen
if (!gegenKonto.startsWith("1")) {
@ -181,7 +183,7 @@ public class DatevCargosoftImportAdapter implements SignalAdapter {
if (invoiceWorkitem == null) {
logger.info("...create new workitem....");
// erzeuge ein neues
invoiceWorkitem =createEmptyInvoice(belegNummer,text,gegenKonto,dateBuchung,dueDate,paymentTerm,waehrung );
invoiceWorkitem =createEmptyInvoice(belegNummer,text,gegenKonto,dateBuchung,dueDate,paymentTerm,waehrung,kurs,basisumsatz );
}
// ist es noch die selbe Belegnummer?
@ -199,7 +201,7 @@ public class DatevCargosoftImportAdapter implements SignalAdapter {
splitBuchungen = new ArrayList<ItemCollection>();
// invoice zurücksetzten
// erzeuge ein neues
invoiceWorkitem =createEmptyInvoice(belegNummer,text,gegenKonto,dateBuchung,dueDate,paymentTerm,waehrung );
invoiceWorkitem =createEmptyInvoice(belegNummer,text,gegenKonto,dateBuchung,dueDate,paymentTerm,waehrung,kurs,basisumsatz );
splitBuchungen.add(dataItemCol);
}
@ -213,7 +215,8 @@ public class DatevCargosoftImportAdapter implements SignalAdapter {
}
private ItemCollection createEmptyInvoice(String belegNummer, String text, String gegenKonto, Date dateBuchung,Date dueDate,String paymentTerm,String currency) {
private ItemCollection createEmptyInvoice(String belegNummer, String text, String gegenKonto, Date dateBuchung,Date dueDate,String paymentTerm,String currency,
double kurs,double basisUmsatz) {
ItemCollection invoiceWorkitem = new ItemCollection();
invoiceWorkitem.setItemValue("invoice.number", belegNummer);
invoiceWorkitem.setItemValue("invoice.currency", currency);
@ -224,6 +227,10 @@ public class DatevCargosoftImportAdapter implements SignalAdapter {
invoiceWorkitem.setItemValue("invoice.reminder", dueDate);
invoiceWorkitem.setItemValue("payment.term",paymentTerm);
invoiceWorkitem.setItemValue("invoice.rate",kurs);
invoiceWorkitem.setItemValue("invoice.base.amount",basisUmsatz);
return invoiceWorkitem;
}

View file

@ -6,7 +6,7 @@
<ul>
<li><h:link outcome="/pages/admin/document_import">Dokument Import</h:link></li>
<li><h:link outcome="/pages/admin/sepa_config">SEPA</h:link></li>
<li><h:link outcome="/pages/admin/datev_config">DATEV</h:link></li>
<li><h:link outcome="/pages/admin/cargosoft_export">Cargosoft Export</h:link></li>
<li><h:link outcome="/pages/admin/analyse_invoicing">Analyse Rechnungseingang</h:link></li>
<li><h:link outcome="/pages/admin/kreditor">Kreditoren Zahlungsziele</h:link></li>
</ul>

View file

@ -0,0 +1,149 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:i="http://java.sun.com/jsf/composite/imixs"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:marty="http://java.sun.com/jsf/composite/marty"
template="/layout/template.xhtml">
<ui:define name="content">
<f:view>
<script type="text/javascript">
/*<![CDATA[*/
function updateStatustPanel(data) {
//initUserInput($('#userselector_id'));
if (data.status === 'success') {
// select with wildcard operator
$('[id$=status_panel]').imixsLayout();
}
}
/*]]>*/
</script>
<h:form id="import_form_id">
<div class="imixs-form">
<div class="imixs-header">
<h1>Ausgangsrechnungen</h1>
<!-- ########## Error ########## -->
<ui:include src="/pages/error_message.xhtml" />
</div>
<div class="imixs-body">
<div class="imixs-tabs">
<ul>
<li><a href="#tab-1">Export - Cargosoft</a></li>
</ul>
<div id="tab-1">
<!-- **** Export Buchunsstapel ***** -->
<div class="imixs-form-section">
<!-- FTP -->
<div class="imixs-form-section-2">
<dl>
<dt>FTP Server / Port</dt>
<dd>
<h:inputText required="false" style="width:85%;"
value="#{cargosoftExportController.configuration.item['_datev_ftp_host']}">
</h:inputText>
:
<h:inputText required="false" style="width:10%;"
value="#{cargosoftExportController.configuration.item['_datev_ftp_port']}">
</h:inputText>
</dd>
</dl>
<dl>
<dt>FTP UserID / Passwort</dt>
<dd>
<h:inputText required="false" style="width:47%;"
value="#{cargosoftExportController.configuration.item['_datev_ftp_userid']}">
</h:inputText>
/
<h:inputSecret required="false" style="width:47%;"
redisplay="true"
value="#{cargosoftExportController.configuration.item['_datev_ftp_password']}">
</h:inputSecret>
</dd>
</dl>
</div>
<!-- FTP Verzeichnisse -->
<div class="imixs-form-section-2">
<dl>
<dt>FTP Verzeichnis Buchungsstapel</dt>
<dd>
<h:inputText required="false"
value="#{cargosoftExportController.configuration.item['_datev_ftp_path_buchungsstapel']}">
</h:inputText>
</dd>
</dl>
<dl>
<dt>FTP Verzeichnis</dt>
<dd>
<h:inputText required="false"
value="#{cargosoftExportController.configuration.item['_datev_ftp_path_belege']}">
</h:inputText>
</dd>
</dl>
<p>
<span class="typcn typcn-lightbulb"></span> Die Verzeichnisse
werden mit der DATEV Mandanten ID ergänzt und müssen vor dem
Export angelegt worden sein!
</p>
</div>
<h2>Scheduler</h2>
<!-- include timer control -->
<ui:include src="sub_scheduler_control.xhtml">
<ui:param name="schedulerController"
value="#{cargosoftExportController}" />
</ui:include>
</div>
</div>
</div>
</div>
<div class="imixs-footer">
<h:outputLabel value="#{message.modified}: " />
<h:outputText
value="#{cargosoftExportController.configuration.item['$modified']}">
<f:convertDateTime timeZone="#{message.timeZone}" type="both"
pattern="#{message.dateTimePattern}" />
</h:outputText>
<br />
<h:commandButton
actionListener="#{cargosoftExportController.saveConfiguration()}"
value="#{message.save}">
</h:commandButton>
<h:commandButton value="#{message.close}" action="notes" />
</div>
</div>
</h:form>
</f:view>
</ui:define>
</ui:composition>

View file

@ -1,263 +0,0 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:i="http://java.sun.com/jsf/composite/imixs"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:marty="http://java.sun.com/jsf/composite/marty"
template="/layout/template.xhtml">
<ui:define name="content">
<f:view>
<script type="text/javascript">
/*<![CDATA[*/
function updateStatustPanel(data) {
//initUserInput($('#userselector_id'));
if (data.status === 'success') {
// select with wildcard operator
$('[id$=status_panel]').imixsLayout();
}
}
/*]]>*/
</script>
<h:form id="import_form_id">
<div class="imixs-form">
<div class="imixs-header">
<h1>DATEV</h1>
<!-- ########## Error ########## -->
<ui:include src="/pages/error_message.xhtml" />
</div>
<div class="imixs-body">
<div class="imixs-tabs">
<ul>
<li><a href="#tab-1">Import</a></li>
<li><a href="#tab-2">Stammdaten</a></li>
</ul>
<div id="tab-1">
<!-- **** Export Buchunsstapel ***** -->
<div class="imixs-form-section">
<div class="ui-state-highlight ui-corner-all"
style="margin-bottom: 10px; padding: .5em;">
<h3>Import DATEV Buchungsstapel</h3>
<p>Definieren Sie hier den Inport eines Buchunsstapel. Der
Import erfolgt im DATEV Standardformat (CSV Datei)</p>
<p>Das Workflow Modell gibt an mit welchem Worklfow die
Datensätze importiert werden sollen</p>
</div>
<div class="imixs-form-section-2">
<dl>
<dt>
Workflow Model Version <span class="imixs-required">*</span>
</dt>
<dd>
<h:inputText required="true"
value="#{datevController.configuration.item['_model_version']}">
</h:inputText>
</dd>
</dl>
<dl>
<dt>
Initial Task <span class="imixs-required">*</span>
</dt>
<dd>
<h:inputText required="true"
value="#{datevController.configuration.item['_initial_task']}">
</h:inputText>
</dd>
</dl>
</div>
<div class="imixs-form-section">
<p>
<span class="typcn typcn-lightbulb"></span> The initial task
must define a report containing the query and style sheet
information. Invoices will be automatically grouped by the
optional attribute "_datev_client_id". The datev workflow may
optional include a "invoice_update" item definition.
</p>
</div>
<!-- FTP -->
<div class="imixs-form-section-2">
<dl>
<dt>FTP Server / Port</dt>
<dd>
<h:inputText required="false" style="width:85%;"
value="#{datevController.configuration.item['_datev_ftp_host']}">
</h:inputText>
:
<h:inputText required="false" style="width:10%;"
value="#{datevController.configuration.item['_datev_ftp_port']}">
</h:inputText>
</dd>
</dl>
<dl>
<dt>FTP UserID / Passwort</dt>
<dd>
<h:inputText required="false" style="width:47%;"
value="#{datevController.configuration.item['_datev_ftp_userid']}">
</h:inputText>
/
<h:inputSecret required="false" style="width:47%;"
redisplay="true"
value="#{datevController.configuration.item['_datev_ftp_password']}">
</h:inputSecret>
</dd>
</dl>
</div>
<!-- FTP Verzeichnisse -->
<div class="imixs-form-section-2">
<dl>
<dt>FTP Verzeichnis Buchungsstapel</dt>
<dd>
<h:inputText required="false"
value="#{datevController.configuration.item['_datev_ftp_path_buchungsstapel']}">
</h:inputText>
</dd>
</dl>
<dl>
<dt>FTP Verzeichnis Belege</dt>
<dd>
<h:inputText required="false"
value="#{datevController.configuration.item['_datev_ftp_path_belege']}">
</h:inputText>
</dd>
</dl>
<p>
<span class="typcn typcn-lightbulb"></span> Die Verzeichnisse
werden mit der DATEV Mandanten ID ergänzt und müssen vor dem
Export angelegt worden sein!
</p>
</div>
<h2>Scheduler</h2>
<!-- include timer control -->
<ui:include src="sub_scheduler_control.xhtml">
<ui:param name="schedulerController"
value="#{datevController}" />
</ui:include>
</div>
</div>
<div id="tab-2">
<!-- **** DATEV import ***** -->
<div class="imixs-form-section">
<div class="ui-state-highlight ui-corner-all"
style="margin-bottom: 10px; padding: .5em;">
<h3>Import DATEV Stammdaten</h3>
<ul>
<li>Fügen Sie hier die zu importierende DATEV Datei an.</li>
<li>Die Datei muss im CSV Format vorliegen.</li>
<li>Die Datei muss zwei Header Zeilen enthalten:
<ol>
<li>Zeile: Datenart - z.B. "Kontobeschriftungen"</li>
<li>Zeile: Feldbezeichnungen - z.B. "Konto,
Kontobezeichnung"</li>
</ol>
</li>
<li>Fügen Sie immer nur eine Datei für den Import an!</li>
<li>Der Import kann einige Minuten in Anspruch nehmen.</li>
<li>Brechen Sie den Vorgang nicht ab und warten Sie bis
der Import vollständig abgeschlossen ist.</li>
</ul>
</div>
<dl>
<dt>Importdatei wählen:</dt>
<dd>
<i:imixsFileUpload id="file_upload_id"
workitem="#{kriegerImportController.importData}"
context_url="#{facesContext.externalContext.requestContextPath}/rest-service/workflow/workitem/#{workflowController.workitem.item['$uniqueid']}"
hideatachments="true" />
<h:panelGroup layout="block"
styleClass="ui-state-highlight ui-corner-all"
style="margin-bottom: 10px; padding: .5em;"
rendered="#{! empty kriegerImportController.importData.item['log']}">
<pre>#{kriegerImportController.importData.item['log']}</pre>
</h:panelGroup>
</dd>
</dl>
<h:commandButton
actionListener="#{kriegerImportController.startImport}"
value="Start Import">
</h:commandButton>
</div>
</div>
</div>
</div>
<div class="imixs-footer">
<h:outputLabel value="#{message.modified}: " />
<h:outputText
value="#{datevController.configuration.item['$modified']}">
<f:convertDateTime timeZone="#{message.timeZone}" type="both"
pattern="#{message.dateTimePattern}" />
</h:outputText>
<br />
<h:commandButton
actionListener="#{datevController.saveConfiguration()}"
value="#{message.save}">
</h:commandButton>
<h:commandButton value="#{message.close}" action="notes" />
</div>
</div>
</h:form>
</f:view>
</ui:define>
</ui:composition>