This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

- Redundanten Code aus den Generatoren (XMLGregorianCalendar) sowie d…

…ie Parameter-Index-Methoden in Util-Klasse "SepaUtil" verschoben

- Timestamps in "CreDtTm" ohne Millisekunden (macht ProfiCash auch so)
- In "MsgId" und "PmtInfId" nicht mehr die Userkennung schicken sondern Produktname + Zeistempel (macht ProfiCash auch so)
- Sicherstellen, dass als EndToEndId immer "NOTPROVIDED" geschickt wird, wenn keine angegeben ist
- "BtchBookg" immer mitschicken - auch wenn es der Default-Wert "true" ist (macht ProfiCash auch so)

Siehe http://www.onlinebanking-forum.de/forum/topic.php?t=17173
  • Loading branch information...
willuhn committed Feb 28, 2014
1 parent 92443f3 commit 04ec58ac90510aae6707643a05acb536b1f0e9c3
@@ -32,7 +32,7 @@
* Nach Ruecksprache mit Holger vom onlinebanking-forum.de weiss ich aber, dass VRNetworld
* den auch verwendet und er von Banken als solcher erkannt wird.
*/
protected final static String ENDTOEND_ID_NOTPROVIDED = "NOTPROVIDED";
public final static String ENDTOEND_ID_NOTPROVIDED = "NOTPROVIDED";
protected final Properties sepaParams = new Properties();
private PainVersion pain = null;
@@ -263,28 +263,14 @@ public String getSEPAMessageId()
String result = getSEPAParam("messageId");
if (result == null)
{
Date now = new Date();
result = now.getTime() + "-" + getMainPassport().getUserId();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSS");
result = "hbci4java-" + format.format(new Date());
result = result.substring(0, Math.min(result.length(), 35));
setSEPAParam("messageId", result);
}
return result;
}
/**
* Erstellt einen Timestamp im ISODateTime Forma.
*
* @discuss Diese methode wäre bestimmt auch gut in der SEPAGeneratorFactory
* oder den einzelnen Generator Klassen nützlich
* @return Aktuelles Datum als ISODateTime String
*/
public String createSEPATimestamp()
{
Date now = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
return format.format(now);
}
/**
* Liefert den passenden SEPA-Generator.
* @return der SEPA-Generator.
@@ -5,7 +5,6 @@
package org.kapott.hbci.GV;
import org.kapott.hbci.GV.generators.AbstractSEPAGenerator;
import org.kapott.hbci.GV_Result.AbstractGVRLastSEPA;
import org.kapott.hbci.GV_Result.GVRLastB2BSEPA;
import org.kapott.hbci.manager.HBCIHandler;
@@ -54,6 +53,6 @@ public GVMultiLastB2BSEPA(HBCIHandler handler, String lowlevelName, AbstractGVRL
@Override protected void createSEPAFromParams()
{
super.createSEPAFromParams();
setParam("Total", ((AbstractSEPAGenerator) getSEPAGenerator()).sumBtgValueObject(sepaParams));
setParam("Total", SepaUtil.sumBtgValueObject(sepaParams));
}
}
@@ -5,7 +5,6 @@
package org.kapott.hbci.GV;
import org.kapott.hbci.GV.generators.AbstractSEPAGenerator;
import org.kapott.hbci.GV_Result.AbstractGVRLastSEPA;
import org.kapott.hbci.GV_Result.GVRLastCOR1SEPA;
import org.kapott.hbci.manager.HBCIHandler;
@@ -54,6 +53,6 @@ public GVMultiLastCOR1SEPA(HBCIHandler handler, String lowlevelName, AbstractGVR
@Override protected void createSEPAFromParams()
{
super.createSEPAFromParams();
setParam("Total", ((AbstractSEPAGenerator) getSEPAGenerator()).sumBtgValueObject(sepaParams));
setParam("Total", SepaUtil.sumBtgValueObject(sepaParams));
}
}
@@ -5,7 +5,6 @@
package org.kapott.hbci.GV;
import org.kapott.hbci.GV.generators.AbstractSEPAGenerator;
import org.kapott.hbci.GV_Result.AbstractGVRLastSEPA;
import org.kapott.hbci.GV_Result.GVRLastSEPA;
import org.kapott.hbci.manager.HBCIHandler;
@@ -54,6 +53,6 @@ public GVMultiLastSEPA(HBCIHandler handler, String lowlevelName, AbstractGVRLast
@Override protected void createSEPAFromParams()
{
super.createSEPAFromParams();
setParam("Total", ((AbstractSEPAGenerator) getSEPAGenerator()).sumBtgValueObject(sepaParams));
setParam("Total", SepaUtil.sumBtgValueObject(sepaParams));
}
}
@@ -21,7 +21,6 @@
package org.kapott.hbci.GV;
import org.kapott.hbci.GV.generators.AbstractSEPAGenerator;
import org.kapott.hbci.manager.HBCIHandler;
import org.kapott.hbci.manager.LogFilter;
@@ -76,6 +75,6 @@ public GVMultiUebSEPA(HBCIHandler handler, String name)
@Override protected void createSEPAFromParams()
{
super.createSEPAFromParams();
setParam("Total", ((AbstractSEPAGenerator) getSEPAGenerator()).sumBtgValueObject(sepaParams));
setParam("Total", SepaUtil.sumBtgValueObject(sepaParams));
}
}
@@ -0,0 +1,158 @@
package org.kapott.hbci.GV;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.kapott.hbci.exceptions.InvalidArgumentException;
import org.kapott.hbci.structures.Value;
/**
* Ein paar statische Hilfs-Methoden fuer die Generierung der SEPA-Nachrichten.
*/
public class SepaUtil
{
private final static String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
private final static Pattern INDEX_PATTERN = Pattern.compile("\\w+\\[(\\d+)\\](\\..*)?");
/**
* Erzeugt ein neues XMLCalender-Objekt.
* @param isoDate optional. Das zu verwendende Datum.
* Wird es weggelassen, dann wird das aktuelle Datum (mit Uhrzeit) verwendet.
* @return das XML-Calendar-Objekt.
* @throws Exception
*/
public static XMLGregorianCalendar createCalendar(String isoDate) throws Exception
{
if (isoDate == null)
{
SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN);
isoDate = format.format(new Date());
}
DatatypeFactory df = DatatypeFactory.newInstance();
return df.newXMLGregorianCalendar(isoDate);
}
/**
* Ermittelt den maximalen Index aller indizierten Properties. Nicht indizierte Properties
* werden ignoriert.
*
* @param properties die Properties, mit denen gearbeitet werden soll
* @return Maximaler Index, oder {@code null}, wenn keine indizierten Properties gefunden wurden
*/
public static Integer maxIndex(Properties properties)
{
Integer max = null;
for (String key : properties.stringPropertyNames())
{
Matcher m = INDEX_PATTERN.matcher(key);
if (m.matches())
{
int index = Integer.parseInt(m.group(1));
if (max == null || index > max)
{
max = index;
}
}
}
return max;
}
/**
* Liefert die Summe der Beträge aller Transaktionen. Bei einer Einzeltransaktion wird der
* Betrag zurückgeliefert. Mehrfachtransaktionen müssen die gleiche Währung verwenden, da
* eine Summenbildung sonst nicht möglich ist.
*
* @param sepaParams die Properties, mit denen gearbeitet werden soll
* @param max Maximaler Index, oder {@code null} für Einzeltransaktionen
* @return Summe aller Beträge
*/
public static BigDecimal sumBtgValue(Properties sepaParams, Integer max)
{
if (max == null)
return new BigDecimal(sepaParams.getProperty("btg.value"));
BigDecimal sum = BigDecimal.ZERO;
String curr = null;
for (int index = 0; index <= max; index++)
{
sum = sum.add(new BigDecimal(sepaParams.getProperty(insertIndex("btg.value", index))));
// Sicherstellen, dass alle Transaktionen die gleiche Währung verwenden
String indexCurr = sepaParams.getProperty(insertIndex("btg.curr", index));
if (curr != null)
{
if (!curr.equals(indexCurr)) {
throw new InvalidArgumentException("mixed currencies on multiple transactions");
}
}
else
{
curr = indexCurr;
}
}
return sum;
}
/**
* Fuegt einen Index in den Property-Key ein. Wurde kein Index angegeben, wird der Key
* unveraendert zurueckgeliefert.
*
* @param key Key, der mit einem Index ergaenzt werden soll
* @param index Index oder {@code null}, wenn kein Index gesetzt werden soll
* @return Key mit Index
*/
public static String insertIndex(String key, Integer index)
{
if (index == null)
return key;
int pos = key.indexOf('.');
if (pos >= 0)
{
return key.substring(0, pos) + '[' + index + ']' + key.substring(pos);
}
else
{
return key + '[' + index + ']';
}
}
/**
* Liefert ein Value-Objekt mit den Summen des Auftrages.
* @param properties Auftrags-Properties.
* @return das Value-Objekt mit der Summe.
*/
public static Value sumBtgValueObject(Properties properties)
{
Integer maxIndex = maxIndex(properties);
BigDecimal btg = sumBtgValue(properties, maxIndex);
String curr = properties.getProperty(insertIndex("btg.curr", maxIndex == null ? null : 0));
return new Value(btg, curr);
}
/**
* Liefert den Wert des Properties oder den Default-Wert.
* Der Default-Wert wird nicht nur bei NULL verwendet sondern auch bei Leerstring.
* @param props die Properties.
* @param name der Name des Properties.
* @param defaultValue der Default-Wert.
* @return der Wert.
*/
public static String getProperty(Properties props, String name, String defaultValue)
{
String value = props.getProperty(name);
return value != null && value.length() > 0 ? value : defaultValue;
}
}
Oops, something went wrong.

0 comments on commit 04ec58a

Please sign in to comment.