package com.alexanderlogistics; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.imixs.workflow.exceptions.PluginException; import org.junit.Before; import org.junit.Test; import junit.framework.Assert; public class MigrationMahnerDatev { List doppelteBuchungen = new ArrayList(); List rechnungsnummern = new ArrayList(); String WJ = "2022"; @Before public void setup() throws PluginException { doppelteBuchungen = new ArrayList(); rechnungsnummern = new ArrayList(); } /** * Diese Test Method wandelt die Datei OPD_migration_230126.csv in eine EXTV * Datev Datei um, welche wir dann für einen einmaligen Import der * Rechnugnsdaten verwenden können. * */ @Test public void migriere() { System.out.println("***********************"); System.out.println("* OP Listen Migration *"); System.out.println("* Wirtschaftsjahr " + WJ + " *"); System.out.println("***********************"); String filename_input = "datev/OPD_migration_230126.csv"; String filename_output = "src/test/resources/datev/EXTF_OPD_migration_" + WJ + ".csv"; FileInputStream fis; BufferedReader br = null; try { ClassLoader classLoader = this.getClass().getClassLoader(); File inputFile = new File(classLoader.getResource(filename_input).getFile()); Assert.assertTrue(inputFile.exists()); fis = new FileInputStream(inputFile); DataInputStream in = new DataInputStream(fis); br = new BufferedReader(new InputStreamReader(in, "ISO-8859-1")); // read the first line containing the field names String fieldnames = br.readLine(); Assert.assertTrue(fieldnames.contains("Kontonummer")); // write output file... BufferedWriter writer = new BufferedWriter(new FileWriter(filename_output)); writeEXTFHeader(writer,WJ); // Jetzt iterieren wir über die Input Datei und schreiben jeweilse eine Zeile // in die Output Datei... String line; int count = 0; int count2021 = 0; int count2022 = 0; int count2023 = 0; while ((line = br.readLine()) != null) { String[] data = line.split(";(?=([^\"]*\"[^\"]*\")*[^\"]*$)", 999); if (data.length != 90) { System.out.println("Fehlerhafte Daten in Zeile " + count); System.out.println(line); Assert.fail(); } String wj = data[3]; wj = wj.substring(wj.length() - 4); if (wj.equals("2021")) { count2021++; } if (wj.equals("2022")) { count2022++; } if (wj.equals("2023")) { count2023++; } // Nur einlesen falls das Wirtschfsjahr passt if (WJ.equals(wj)) { writeOutputLine(writer, data, count); } count++; // if (count>25) { // break; // } } writer.close(); System.out.println("... fininshed - read " + count + " lines."); System.out.println("... wj 2021= " + count2021); System.out.println("... wj 2022= " + count2022); System.out.println("... wj 2023= " + count2023); System.out.println("... Besondere Buchungen :"); for (String rgn : doppelteBuchungen) { System.out.println(" Rechnungs-Nr: " + rgn); } } catch (IOException e) { e.printStackTrace(); Assert.fail(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); Assert.fail(); } } } } /** * Hilfsmethode die einen DATEV Header schreibt * * @param writer * @throws IOException */ private void writeEXTFHeader(BufferedWriter writer,String wj) throws IOException { writer.write( "\"EXTF\";\"510\";21;\"Buchungsstapel\";7;\"20220721060421653\";\"\";\"CS\";\"cargoservice\";\"\";\"\";\"\";\"" + WJ + "0101\";\"4\";\"" + WJ + "0101\";\"" + WJ + "1231\";\"202206ALL\";\"CS\";\"\";\"\";0;\"EUR\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\""); writer.newLine(); writer.write( "Umsatz (ohne Soll-/Haben-Kennzeichen);Soll-Haben-Kennzeichen;WKZ Umsatz;Kurs;Basisumsatz;WKZ Basisumsatz;Konto;Gegenkonto;BU-Schlüssel;Belegdatum;Belegfeld 1;Belegfeld 2;Skonto;Buchungstext;Postensperre;Diverse Adressnummer;Geschäftspartnerbank;Sachverhalt;Zinssperre;Beleglink;Beleginfo-Art 1;Beleginfo-Inhalt 1;Beleginfo-Art 2;Beleginfo-Inhalt 2;Beleginfo-Art 3;Beleginfo-Inhalt 3;Beleginfo-Art 4;Beleginfo-Inhalt 4;Beleginfo-Art 5;Beleginfo-Inhalt 5;Beleginfo-Art 6;Beleginfo-Inhalt 6;Beleginfo-Art 7;Beleginfo-Inhalt 7;Beleginfo-Art 8;Beleginfo-Inhalt 8;KOST1-Kostenstelle;KOST2-Kostenstelle;KOST-Menge;EU-Mitgliedstaatu. USt-IdNr.;EU-Steuersatz;Abw. Versteuerungsart;Sachverhalt L+L;Funktionserg�nzung L+L;BU 49 Hauptfunktionstyp;BU 49 Hauptfunktionsnummer;BU 49 Funktionserg�nzung;Zusatzinformation-Art 1;Zusatzinformation-Inhalt 1;Zusatzinformation-Art 2;Zusatzinformation-Inhalt 2;Zusatzinformation-Art 3;Zusatzinformation-Inhalt 3;Zusatzinformation-Art 4;Zusatzinformation-Inhalt 4;Zusatzinformation-Art 5;Zusatzinformation-Inhalt 5;Zusatzinformation-Art 6;Zusatzinformation-Inhalt 6;Zusatzinformation-Art 7;Zusatzinformation-Inhalt 7;Zusatzinformation-Art 8;Zusatzinformation-Inhalt 8;Zusatzinformation-Art 9;Zusatzinformation-Inhalt 9;Zusatzinformation-Art 10;Zusatzinformation-Inhalt 10;Zusatzinformation-Art 11;Zusatzinformation-Inhalt 11;Zusatzinformation-Art 12;Zusatzinformation-Inhalt 12;Zusatzinformation-Art 13;Zusatzinformation-Inhalt 13;Zusatzinformation-Art 14;Zusatzinformation-Inhalt 14;Zusatzinformation-Art 15;Zusatzinformation-Inhalt 15;Zusatzinformation-Art 16;Zusatzinformation-Inhalt 16;Zusatzinformation-Art 17;Zusatzinformation-Inhalt 17;Zusatzinformation-Art 18;Zusatzinformation-Inhalt 18;Zusatzinformation-Art 19;Zusatzinformation-Inhalt 19;Zusatzinformation-Art 20;Zusatzinformation-Inhalt 20;St�ck;Gewicht;Zahlweise;Forderungsart;Veranlagungsjahr;Zugeordnete F�lligkeit;Skontotyp;Auftragsnummer;Buchungstyp;USt-Schl�ssel (Anzahlungen);EU-Mitgliedstaat (Anzahlungen);Sachverhalt L+L (Anzahlungen);EU-Steuersatz (Anzahlungen);Erlöskonto (Anzahlungen);Herkunft-Kz;Leerfeld;KOST-Datum;SEPAMandatsreferenz;Skontosperre;Gesellschaftername;Beteiligtennummer;Identifikationsnummer;Zeichnernummer;Postensperre bis;Bezeichnung SoBil-Sachverhalt;Kennzeichen SoBil-Buchung;Festschreibung;Leistungsdatum;Datum Zuord. Steuerperiode"); writer.newLine(); } /** * Schreibt eine einzelen Datenzeile * * @param writer * @param data * @throws IOException */ private void writeOutputLine(BufferedWriter writer, String[] data, int line) throws IOException { String rechnungsNummer = data[2]; String rechnungsDatum=data[3]; String faelligkeit=data[4]; String saldo=data[7]; String zahlung=data[6]; // vertasuchen if (faelligkeit.length()==8) { faelligkeit=faelligkeit.substring(4,8)+faelligkeit.substring(2,4)+faelligkeit.substring(0,2); } else { faelligkeit="20230125"; } String text=data[18]; String basisumsatz = "0,00"; String umsatz = data[5]; if ("0,00".equals(umsatz)) { umsatz = data[6]; } if ("0,00".equals(umsatz)) { System.out.println("ACHTUNG - Fehler in Spalte 5 bzw. 6 in zeile " + line); } String sh = data[8]; String wkz = data[9]; if (isEmpty(wkz)) { wkz = "\"EUR\""; } else { umsatz = data[10]; basisumsatz = data[5]; if ("0,00".equals(basisumsatz)) { basisumsatz = data[6]; } } String kurs = data[11]; String gegenkonto = data[0]; String konto = data[12]; boolean skip=false; if (rechnungsnummern.contains(rechnungsNummer)) { doppelteBuchungen.add(rechnungsNummer + "\tZahlung=" + zahlung + "\tSaldo="+saldo); skip=true; } rechnungsnummern.add(rechnungsNummer); if (skip) { return; } // umdrehen von sh if ("\"H\"".equals(sh)) { sh="\"S\""; } else { sh="\"H\""; } // umsätze writer.write(umsatz + ";" + sh + ";" + wkz + ";" + kurs + ";" + basisumsatz + ";"); // wkz if (wkz.equals("\"EUR\"")) { writer.write(";"); } else { writer.write("\"EUR\";"); } // konten writer.write(konto + ";" + gegenkonto + ";;"); // datum und rechnungsnummer writer.write(rechnungsDatum.substring(0,4) + ";" + rechnungsNummer + ";;;"+text + ";0;;;0;;;;;Faelligkeit;"+faelligkeit+";"); writer.write(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"); writer.newLine(); } private boolean isEmpty(String data) { return (data.isEmpty() || "\"\"".equals(data)); } }