Skip to content

Commit

Permalink
impl
Browse files Browse the repository at this point in the history
Issue #152
  • Loading branch information
rsoika committed Jan 24, 2024
1 parent 6b1c767 commit 3afcfd4
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 308 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import jakarta.annotation.security.DeclareRoles;
import jakarta.annotation.security.RunAs;
import jakarta.ejb.LocalBean;
import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
import jakarta.xml.bind.JAXBException;
import javax.xml.transform.TransformerException;

import org.apache.commons.net.ftp.FTPClient;
Expand All @@ -71,7 +65,12 @@
import org.imixs.workflow.xml.XMLDataCollectionAdapter;
import org.imixs.workflow.xml.XSLHandler;


import jakarta.annotation.security.DeclareRoles;
import jakarta.annotation.security.RunAs;
import jakarta.ejb.LocalBean;
import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
import jakarta.xml.bind.JAXBException;

/**
* Der DatevExportService stellt methoden für den Datev export bereit
Expand All @@ -94,33 +93,33 @@
@DeclareRoles({ "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
@Stateless
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
@LocalBean
@LocalBean
public class DatevExportService {

public static final String ITEM_DATEV_KONTENLAENGE = "_datev_sachkontennummernlaenge";
public static final String ITEM_FTP_HOST = "_datev_ftp_host";
public static final String ITEM_FTP_PORT = "_datev_ftp_port";
public static final String ITEM_FTP_USER = "_datev_ftp_userid";
public static final String ITEM_FTP_PASSWORD = "_datev_ftp_password";
public static final String ITEM_FTP_PATH_UPLOAD = "_datev_ftp_path_upload";
public static final String ITEM_DATEV_KONTENLAENGE = "datev.sachkontennummernlaenge";

public static final String ITEM_FTP_HOST = "datev.ftp.host";
public static final String ITEM_FTP_PORT = "datev.ftp.port";
public static final String ITEM_FTP_USER = "datev.ftp.userid";
public static final String ITEM_FTP_PASSWORD = "datev.ftp.password";
public static final String ITEM_FTP_PATH_UPLOAD = "_datev.ftp.path.upload";
public static final String ITEM_FTP_ERROR = "_ftp_error";

public static final String ITEM_DATEV_CLIENT_ID = "_datev_client_id";
public static final String ITEM_DATEV_BOOKING_PERIOD = "_datev_booking_period";
public static final String ITEM_DATEV_CONSULTANT_ID = "_datev_consultant_id";
public static final String ITEM_DATEV_FISCAL_START = "_datev_fiscal_start";

public static final String ITEM_DBTR_NAME = "_dbtr_name";
public static final String CHILD_ITEM_PROPERTY = "_ChildItems";
public static final String ITEM_DATEV_CLIENT_ID = "datev.client.id";
public static final String ITEM_DATEV_CLIENT_NAME = "datev.client.name";
public static final String ITEM_DATEV_BOOKING_PERIOD = "datev.booking_period";
public static final String ITEM_DATEV_CONSULTANT_ID = "datev.consultant.id";
public static final String ITEM_DATEV_FISCAL_START = "datev.fiscal_start";

// public static final String ITEM_DBTR_NAME = "dbtr.name";

public static final String DEFAULT_CONFIG_NAME = "DATEV_CONFIGURATION";

public static final String CHILD_ITEM_PROPERTY = "_ChildItems";

public static final String REPORT_ERROR = "REPORT_ERROR";
public static final String MODEL_ERROR = "MODEL_ERROR";


@Inject
WorkflowService workflowService;

Expand All @@ -138,19 +137,16 @@ public class DatevExportService {
* The datev client id is fetched from the first invoice of the invoice data
* collection.
* <p>
* Change 5.5.2022
*
* Die Beraternummer kann nun auch auf Corporate Ebene gepflegt werden. Ist das
* der Fall, dann gewinnt diese Nummer. Andernfalls wird weiterhin die
* Beraternummer aus der Zentralen DATEV Config genommen.
*
* @param configuration
* @param modelVersion
* @param taskID
* @param data
* @return
*/
public ItemCollection updateExportWorkitem(ItemCollection datevExport, ItemCollection configuration,
public ItemCollection updateExportWorkitem(ItemCollection datevExport,
ItemCollection configuration,
List<ItemCollection> data) {

// set _datev_fiscal_start (date), clientID and Sachkontenlaenge from first
Expand All @@ -165,11 +161,6 @@ public ItemCollection updateExportWorkitem(ItemCollection datevExport, ItemColle
// copy sachkontenlaenge from first invoice..
datevExport.setItemValue(ITEM_DATEV_KONTENLAENGE,
firstInvoice.getItemValue(ITEM_DATEV_KONTENLAENGE));

// Copy Consultant ID if available (die nummber ist optional auf Corporate Ebene
// gepflegt)
datevExport.setItemValue(ITEM_DATEV_CONSULTANT_ID,
firstInvoice.getItemValue(ITEM_DATEV_CONSULTANT_ID));
}
}

Expand Down Expand Up @@ -198,14 +189,14 @@ public ItemCollection updateExportWorkitem(ItemCollection datevExport, ItemColle
* @param data
* @return
* @throws SchedulerException
* @throws PluginException
* @throws PluginException
*/
public void buildDocumentsZipFile(ItemCollection datevExport, List<ItemCollection> data, String key,
ItemCollection configuration) throws SchedulerException, PluginException {
int documentCount = 0;
ZipOutputStream datevZip = null;
ByteArrayOutputStream zipOutputStream = null;

DatevHelper.logMessage(
"... Document export started (ClientID="
+ datevExport.getItemValueString(ITEM_DATEV_CLIENT_ID) + ") ...",
Expand Down Expand Up @@ -360,21 +351,21 @@ public void buildDocumentsZipFile(ItemCollection datevExport, List<ItemCollectio
*/
public void buildCSVFile(ItemCollection datevExport, List<ItemCollection> data, String key,
ItemCollection configuration) throws SchedulerException {
String clientID=datevExport.getItemValueString(ITEM_DATEV_CLIENT_ID);
String clientID = datevExport.getItemValueString(ITEM_DATEV_CLIENT_ID);
DatevHelper.logMessage(
"... CSV export started (ClientID="
+ clientID + ") ...",
configuration, datevExport);

// load the report for CSV export
String reportNameInvoices = configuration.getItemValueString("_report_invoices");
// It is possible, that we have an optional report definition for this client ID

// It is possible, that we have an optional report definition for this client ID
// let's test this
ItemCollection invoiceReport=null;
invoiceReport = reportService.findReport(reportNameInvoices+"_" +clientID);
if (invoiceReport== null) {
// load default
ItemCollection invoiceReport = null;
invoiceReport = reportService.findReport(reportNameInvoices + "_" + clientID);
if (invoiceReport == null) {
// load default
invoiceReport = reportService.findReport(reportNameInvoices);
}
if (invoiceReport == null) {
Expand Down Expand Up @@ -663,24 +654,18 @@ public ItemCollection loadConfiguration(String name) {
*
* @return
*/
public String computeKey(ItemCollection invoice) {
String datevClientID = invoice.getItemValueString(ITEM_DATEV_CLIENT_ID);
Date datInvoice = invoice.getItemValueDate("_invoicedate");
public String computeKey(ItemCollection invoice, String datevClientID) {

Date datInvoice = invoice.getItemValueDate("invoice.date");

// Berechnung der Buchungsperiode
DateFormat df = new SimpleDateFormat("yyyyMM");
String keyPeriode = df.format(datInvoice);
// 9.6.2022: Rechnungen sollen nicht nach Buchungsperiode gruppiert werden
// wir haben das aber zurückgezogen, da es in DATEV probleme mit überlappenden
// Wirtschaftsjahren geben kann
// String key = datevClientID;
String key = keyPeriode + "_" + datevClientID;

return key;
}




/**
* Prüft alle offenen Datev Exporte und gibt den neuesten zur angegebenen Datev
* Client ID zurück, oder null falls es keinen Offenen Datev Export gibt.
Expand All @@ -701,30 +686,26 @@ public ItemCollection findDatevExport(String datevKey) throws QueryException {
// no datev export found
return null;
}



/**
* Aktualisiert den DATEV Export mit Manager Rechten
*
* @param datevExport
* @return
* @throws ModelException
* @throws PluginException
* @throws ProcessingErrorException
* @throws AccessDeniedException
* @throws ModelException
* @throws PluginException
* @throws ProcessingErrorException
* @throws AccessDeniedException
*/
public ItemCollection processDatevExport(ItemCollection datevExport) throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException {
public ItemCollection processDatevExport(ItemCollection datevExport)
throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException {
return workflowService.processWorkItem(datevExport);
}







/**
* This method first lookups the origin workItem from the given export
* data entity. Then the method returns the first PDF fileData from a snapshot by a
* data entity. Then the method returns the first PDF fileData from a snapshot
* by a
* resolved invoice workItem.
* <p>
* If multiple files are attached, the method returns the latest FileData object
Expand All @@ -733,13 +714,11 @@ public ItemCollection processDatevExport(ItemCollection datevExport) throws Acce
* @param uniqueid
* @param file - file name
* @return FileData object for the given filename.
* @throws PluginException
* @throws PluginException
*/
public FileData getWorkItemFileFromWorkitem(ItemCollection invoice) throws PluginException {
String snapshotID;



if (invoice != null) {
// we found the corresponding invoice workitem!

Expand Down Expand Up @@ -779,11 +758,9 @@ public FileData getWorkItemFileFromWorkitem(ItemCollection invoice) throws Plugi
throw new PluginException(DatevExportService.class.getName(), MODEL_ERROR,
"Invoice Document not defined");
}



// no file found!
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import java.util.Map;
import java.util.logging.Logger;

import jakarta.inject.Inject;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.SignalAdapter;
Expand All @@ -21,6 +19,8 @@
import org.imixs.workflow.exceptions.ProcessingErrorException;
import org.imixs.workflow.exceptions.QueryException;

import jakarta.inject.Inject;

/**
* Der DATEVRefAdapter verknüpft eine Rechnung mit einem DATEV Export zum
* aktuellen Kreiditor und der Buchungsperiode. Existiert aktuell kein offener
Expand All @@ -30,12 +30,7 @@
* Wurde die Rechnugn bereits einem DATEV Export zugeordnet passiert nichts.
* <p>
* Existieren innerhalb der Rechnung noch keien Detailbuchugnssätze (ChildItems)
* dann erzeugt der ADaper einen Default Buchungssatz . Zitat Herr Krieger: die
* leeren Felder könnte man z.B. immer mit 1370 an 70000 im Standard befüllen,
* dann weiß man welche Konten man in DATEV noch aufräumen muss?
* <p>
* 9.6.2022 Herr Krieger: Die Rechnungen sollen NICHT nach Buchunsperiode
* zusammengefasst werden sonder nur anhand der Datev-client-id.
* dann erzeugt der Adaper einen Default Buchungssatz .
*
*
* @version 1.0
Expand All @@ -48,14 +43,12 @@ public class DatevRefAdapter implements SignalAdapter {
public static final String ERROR_MISSING_DATA = "MISSING_DATA";
public static final String ERROR_CONFIG = "CONFIG_ERROR";



@Inject
@ConfigProperty(name = "datev.defaultkonto", defaultValue = "1370")
private String datevDefaultKonto;

@Inject
DatevExportService kriegerDatevService;
DatevExportService datevExportService;

/**
* This method finds or create the Datev Export and adds a reference
Expand All @@ -80,35 +73,43 @@ public ItemCollection execute(ItemCollection document, ItemCollection event)
*/
@SuppressWarnings("unchecked")
private void appendInvoice(ItemCollection invoice) throws PluginException {
String datevClientID = invoice.getItemValueString(DatevExportService.ITEM_DATEV_CLIENT_ID);

if (datevClientID == null || datevClientID.isEmpty()) {
ItemCollection datevConfig = datevExportService.loadConfiguration(DatevExportService.DEFAULT_CONFIG_NAME);
if (datevConfig == null) {
throw new PluginException(PluginException.class.getName(), ERROR_MISSING_DATA,
"Datev Export kann nicht erzeugt werden da keine DATEV Client ID definiert wurde. Bitte prüfen Sie die Corporate Konfiguration.");
"Datev Export kann nicht erzeugt werden da keine DATEV Konfiguration vorliegt.");
}

Date datInvoice = invoice.getItemValueDate("_invoicedate");
String datevClientID = datevConfig.getItemValueString(DatevExportService.ITEM_DATEV_CLIENT_ID);

if (datevClientID == null || datevClientID.isEmpty()) {
throw new PluginException(PluginException.class.getName(), ERROR_MISSING_DATA,
"Datev Export kann nicht erzeugt werden da keine DATEV Client ID definiert wurde. Bitte prüfen Sie die DATEV Konfiguration.");
}

Date datInvoice = invoice.getItemValueDate("invoice.date");
if (datInvoice == null) {
throw new PluginException(PluginException.class.getName(), ERROR_MISSING_DATA,
"Datev Export kann nicht erzeugt werden da kein Buchungsdatum angegeben wurde.");
}
String key=kriegerDatevService.computeKey(invoice);

String key = datevExportService.computeKey(invoice, datevClientID);
// Optional - Berechnung der Buchungsperiode
DateFormat df = new SimpleDateFormat("yyyy/MM");
String keyPeriode = df.format(datInvoice);

logger.info("......Update DATEV export for: '" + key + "'...");
ItemCollection datevExport;
try {
datevExport = kriegerDatevService.findDatevExport(key);
datevExport = datevExportService.findDatevExport(key);
if (datevExport == null) {
// create a new one
datevExport = new ItemCollection().workflowGroup("DATEV-Export").task(1000);
// add cdtr.name
datevExport.setItemValue(DatevExportService.ITEM_DATEV_CLIENT_ID, invoice.getItemValue(DatevExportService.ITEM_DATEV_CLIENT_ID));
datevExport.setItemValue(DatevExportService.ITEM_DBTR_NAME, invoice.getItemValue(DatevExportService.ITEM_DBTR_NAME));
datevExport.setItemValue(DatevExportService.ITEM_DATEV_CLIENT_ID,
datevConfig.getItemValue(DatevExportService.ITEM_DATEV_CLIENT_ID));
datevExport.setItemValue(DatevExportService.ITEM_DATEV_CLIENT_NAME,
datevConfig.getItemValue(DatevExportService.ITEM_DATEV_CLIENT_NAME));
datevExport.setItemValue(DatevExportService.ITEM_DATEV_BOOKING_PERIOD, keyPeriode);
datevExport.setItemValue("name", key);
}
Expand All @@ -119,7 +120,7 @@ private void appendInvoice(ItemCollection invoice) throws PluginException {
datevExport.appendItemValueUnique("$workitemref", invoice.getUniqueID());
// set event 100
datevExport.event(100);
kriegerDatevService.processDatevExport(datevExport);
datevExportService.processDatevExport(datevExport);
}

} catch (QueryException | AccessDeniedException | ProcessingErrorException | ModelException e1) {
Expand All @@ -128,16 +129,12 @@ private void appendInvoice(ItemCollection invoice) throws PluginException {

}
}



/**
* Diese Hilfsmethode erzeugt eine Default Buchung wenn bisher keine
* Splitbuchungen bei der Vorkontierung eingetragen wurden.
* <p>
* Zitat Herr Krieger: die leeren Felder könnte man z.B. immer mit 1370 an 70000
* im Standard befüllen, dann weiß man welche Konten man in DATEV noch aufräumen
* muss?
*
*
* @param invoice
*/
Expand All @@ -154,7 +151,7 @@ private void validateDefaultBooking(ItemCollection invoice) {
bookingItem = buchunssaetze.get(0);
}
bookingItem.setItemValue("_konto", datevDefaultKonto);
bookingItem.setItemValue("_amount", invoice.getItemValue("_amount_brutto"));
bookingItem.setItemValue("_amount", invoice.getItemValue("invoice.amount"));

if (buchunssaetze.size() == 1) {
buchunssaetze.remove(0);
Expand Down

0 comments on commit 3afcfd4

Please sign in to comment.