/* $Id: GVWPDepotUms.java 62 2008-10-22 17:03:26Z kleiner $ This file is part of HBCI4Java Copyright (C) 2001-2008 Stefan Palme HBCI4Java 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. HBCI4Java 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 should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.kapott.hbci.GV; import java.text.SimpleDateFormat; import java.util.Properties; import org.kapott.hbci.GV_Result.GVRWPDepotUms; import org.kapott.hbci.GV_Result.GVRWPDepotUms.Entry.FinancialInstrument; import org.kapott.hbci.GV_Result.GVRWPDepotUms.Entry.FinancialInstrument.Transaction; import org.kapott.hbci.exceptions.HBCI_Exception; import org.kapott.hbci.manager.HBCIHandler; import org.kapott.hbci.manager.LogFilter; import org.kapott.hbci.passport.HBCIPassport; import org.kapott.hbci.status.HBCIMsgStatus; import org.kapott.hbci.structures.BigDecimalValue; import org.kapott.hbci.structures.Konto; import org.kapott.hbci.structures.TypedValue; import org.kapott.hbci.swift.Swift; public class GVWPDepotUms extends HBCIJobImpl { private StringBuffer buffer; public static String getLowlevelName() { return "WPDepotUms"; } public GVWPDepotUms(HBCIHandler handler) { super(handler,getLowlevelName(),new GVRWPDepotUms()); this.buffer=new StringBuffer(); HBCIPassport passport=handler.getPassport(); addConstraint("my.number","Depot.number",null, LogFilter.FILTER_IDS); addConstraint("my.subnumber","Depot.subnumber","", LogFilter.FILTER_MOST); addConstraint("my.country","Depot.KIK.country",passport.getUPD().getProperty("KInfo.KTV.KIK.country"), LogFilter.FILTER_NONE); addConstraint("my.blz","Depot.KIK.blz",passport.getUPD().getProperty("KInfo.KTV.KIK.blz"), LogFilter.FILTER_MOST); //addConstraint("my.curr","curr",passport.getUPD().getProperty("KInfo.cur",""), LogFilter.FILTER_NONE); addConstraint("quality","quality","", LogFilter.FILTER_NONE); addConstraint("maxentries","maxentries","", LogFilter.FILTER_NONE); addConstraint("startdate","startdate","", LogFilter.FILTER_NONE); addConstraint("enddate","enddate","", LogFilter.FILTER_NONE); addConstraint("dummy","alldepots","N", LogFilter.FILTER_NONE); } private TypedValue parseTypedValue(String st) { String st_type=st.substring(7,11); String curr=""; boolean withCurr = false; int saldo_type = -1; if (st_type.equals("FAMT")) { saldo_type=TypedValue.TYPE_WERT; } else if (st_type.equals("ACTU")) { saldo_type=TypedValue.TYPE_WERT; withCurr = true; } else if (st_type.equals("UNIT")) { saldo_type=TypedValue.TYPE_STCK; } else if (st_type.equals("PRCT")) { saldo_type=TypedValue.TYPE_PROZENT; } int pos1=12; boolean neg = (st.charAt(pos1)=='N'); if (neg) pos1++; if (withCurr) { curr = st.substring(pos1, pos1+3); pos1 += 3; } return new TypedValue( (neg?"-":"")+st.substring(pos1).replace(',','.'), curr, saldo_type); } protected void extractResults(HBCIMsgStatus msgstatus,String header,int idx) { Properties result=msgstatus.getData(); buffer.append(Swift.decodeUmlauts(result.getProperty(header + ".data536"))); final SimpleDateFormat date_time_format = new SimpleDateFormat("yyyyMMdd hhmmss"); final SimpleDateFormat date_only_format = new SimpleDateFormat("yyyyMMdd"); while (buffer.length()!=0) { try { String onerecord=Swift.getOneBlock(buffer); GVRWPDepotUms.Entry entry=new GVRWPDepotUms.Entry(); String st_timestamp=null; String st_date=null; String st_time=null; char option='C'; int i=0; while (true) { //Parse allgemeine Informationen (Mandatory Sequence A General Information) st_timestamp=Swift.getTagValue(onerecord,"98"+option,i++); if (st_timestamp==null) { if (option=='C') { option='A'; i=0; } else { break; } } else { if (st_timestamp.substring(1,5).equals("PREP")) { st_date=st_timestamp.substring(7,15); if (option=='C') { st_time=st_timestamp.substring(15,21); } break; } } } if (st_time!=null) { entry.timestamp=date_time_format.parse(st_date+" "+st_time); } else if (st_date != null) { entry.timestamp=date_only_format.parse(st_date); } String st_depot=Swift.getTagValue(onerecord,"97A",0); int pos1=st_depot.indexOf("//"); int pos2=st_depot.indexOf("/",pos1+2); if (pos2<0) pos2=st_depot.length(); entry.depot=new Konto(); entry.depot.blz=st_depot.substring(pos1+2,pos2); if (pos2 < st_depot.length()) entry.depot.number=st_depot.substring(pos2+1); getMainPassport().fillAccountInfo(entry.depot); String st; i=0; // Parse einzelnes Finanzinstrument (Repetitive Optional Subsequence B1 Financial Instrument) st=Swift.getTagValue(onerecord,"17B",0); if (st.substring(st.indexOf("//")+2).equals("Y")) { int fin_start=onerecord.indexOf(":16R:FIN"); while (true) { int fin_end=onerecord.indexOf(":16S:FIN",fin_start); if ((fin_end)==-1) { break; } String oneinstrument=onerecord.substring(fin_start,fin_end+8); fin_start+=oneinstrument.length(); FinancialInstrument instrument=new GVRWPDepotUms.Entry.FinancialInstrument(); int trans_start = oneinstrument.indexOf(":16R:TRAN\r\n"); String oneinstrument_header; if (trans_start >= 0) oneinstrument_header = oneinstrument.substring(0, trans_start+9); else oneinstrument_header = oneinstrument; st=Swift.getTagValue(oneinstrument_header,"35B",0); boolean haveISIN=st.substring(0,5).equals("ISIN "); if (haveISIN) { pos1=st.indexOf("\r\n"); instrument.isin=st.substring(5,pos1); if (pos1+2<st.length() && st.substring(pos1+2,pos1+6).equals("/DE/")) { pos2=st.indexOf("\r\n",pos1+6); if (pos2==-1) { pos2=st.length(); } instrument.wkn=st.substring(pos1+6,pos2); pos1=pos2; } } else { pos1=st.indexOf("\r\n"); instrument.wkn=st.substring(4,pos1); } pos1+=2; if (pos1<st.length()) instrument.name=st.substring(pos1); if (instrument.name!=null) { StringBuffer sb=new StringBuffer(instrument.name); int p; while ((p=sb.indexOf("\r\n"))!=-1) { sb.replace(p,p+2," "); } instrument.name=sb.toString(); } i=0; while (true) { st=Swift.getTagValue(oneinstrument_header,"93B",i++); if (st==null) break; String qualifier = st.substring(1,5); if ("FIOP".equals(qualifier) || (instrument.startSaldo == null && "INOP".equals(qualifier))) { instrument.startSaldo = parseTypedValue(st); } else if ("FICL".equals(qualifier) || (instrument.endSaldo == null && "INCL".equals(qualifier))) { instrument.endSaldo = parseTypedValue(st); } else { System.out.println("Unbekannter 93B: " + st); } } i=0; while (true) { st=Swift.getTagValue(oneinstrument_header,"98A",i++); if (st==null) break; String qualifier = st.substring(1,5); if ("PRIC".equals(qualifier)) { instrument.preisdatum = date_only_format.parse(st.substring(7, 15)); } else { System.out.println("Unbekannter 98A: " + st); } } i=0; while (true) { st=Swift.getTagValue(oneinstrument_header,"90A",i++); if (st==null) break; instrument.preis = parseTypedValue(st); } i=0; while (true) { st=Swift.getTagValue(oneinstrument_header,"90B",i++); if (st==null) break; instrument.preis = parseTypedValue(st); } //Parse einzelne Transaktionen while (trans_start >= 0) { int trans_end = oneinstrument.indexOf(":16S:TRAN\r\n", trans_start); if (trans_end<0) break; String onetransaction = oneinstrument.substring(trans_start, trans_end+9); trans_start=trans_end+9; Transaction transaction = new Transaction(); int link_start = onetransaction.indexOf(":16R:LINK"); if (link_start >=0) { int link_end = onetransaction.indexOf(":16S:LINK", link_start); if (link_end >= 0) { String onelink = onetransaction.substring(link_start, link_end+8); String rela = Swift.getTagValue(onelink, "20C", 0); if (rela != null) { transaction.kundenreferenz = rela.substring(7); } } } int detail_start = onetransaction.indexOf(":16R:TRANSDET"); if (detail_start >= 0) { int detail_end = onetransaction.indexOf(":16S:TRANSDET", detail_start); if (detail_end >= 0) { String onedetail = onetransaction.substring(detail_start, detail_end+12); String quantity = Swift.getTagValue(onedetail, "36B", 0); if (quantity != null) if (quantity.startsWith(":PSTA")) { transaction.anzahl = parseTypedValue(quantity); } else { System.out.println("Unbekannter 36B: " + quantity); } String t99a = Swift.getTagValue(onedetail, "99A", 0); if (t99a != null) if (t99a.startsWith(":DAAC")) { int neg = 0; if (t99a.charAt(7) == 'N') neg = 1; transaction.stueckzins_tage = Integer.parseInt(t99a.substring(7+neg)); if (neg != 0) transaction.stueckzins_tage = -transaction.stueckzins_tage; } else { System.out.println("Unbekannter 99A: " + t99a); } int tagidx = 0; while (true) { String t19a = Swift.getTagValue(onedetail, "19A", tagidx++); if (t19a == null) break; if (t19a.startsWith(":PSTA")) { int off=7; if (t19a.charAt(off)=='N') off++; transaction.betrag=new BigDecimalValue( t19a.substring(off+3).replace(',','.'), t19a.substring(off,off+3)); if (off>7) transaction.betrag.setValue(transaction.betrag.getValue().negate()); } else if (t19a.startsWith(":ACRU")) { int off=7; if (t19a.charAt(off)=='N') off++; transaction.stueckzinsen=new BigDecimalValue( t19a.substring(off+3).replace(',','.'), t19a.substring(off,off+3)); if (off>7) transaction.stueckzinsen.setValue(transaction.stueckzinsen.getValue().negate()); } else { System.out.println("Unbekannter 19A: " + t19a); } } tagidx=0; while (true) { String t22f = Swift.getTagValue(onedetail, "22F", tagidx++); if (t22f == null) break; if (t22f.startsWith(":TRAN")) { if (t22f.endsWith("SETT")) { transaction.transaction_indicator = Transaction.INDICATOR_SETTLEMENT_CLEARING; } else if (t22f.endsWith("CORP")) { transaction.transaction_indicator = Transaction.INDICATOR_CORPORATE_ACTION; } else if (t22f.endsWith("BOLE")) { transaction.transaction_indicator = Transaction.INDICATOR_LEIHE; } else if (t22f.endsWith("COLL")) { transaction.transaction_indicator = Transaction.INDICATOR_SICHERHEITEN; } else { System.out.println("Unbekannter 22F->TRAN: " + t22f); transaction.transaction_indicator = -1; } } else if (t22f.startsWith(":CCPT")) { if (t22f.endsWith("YCCP")) { transaction.ccp_eligibility = true; } else { System.out.println("Unbekannter 22F->CCPT: " + t22f); } } else { System.out.println("Unbekannter 22F: " + t22f); } } tagidx=0; while (true) { String t22h = Swift.getTagValue(onedetail, "22H", tagidx++); if (t22h == null) break; if (t22h.startsWith(":REDE")) { if (t22h.endsWith("DELI")) { transaction.richtung = Transaction.RICHTUNG_LIEFERUNG; } else if (t22h.endsWith("RECE")) { transaction.richtung = Transaction.RICHTUNG_ERHALT; } else { System.out.println("Unbekannter 22H->REDE: " + t22h); transaction.richtung = -1; } } else if (t22h.startsWith(":PAYM")) { if (t22h.endsWith("APMT")) { transaction.bezahlung = Transaction.BEZAHLUNG_GEGEN_ZAHLUNG; } else if (t22h.endsWith("FREE")) { transaction.bezahlung = Transaction.BEZAHLUNG_FREI; } else { System.out.println("Unbekannter 22H->PAYM: " + t22h); transaction.bezahlung = -1; } } else { System.out.println("Unbekannter 22F: " + t22h); } } tagidx=0; while (true) { String t98a = Swift.getTagValue(onedetail, "98A", tagidx++); if (t98a == null) break; if (t98a.startsWith(":ESET")) { String datum = t98a.substring(7); transaction.datum = date_only_format.parse(datum); } else if (t98a.startsWith(":SETT")) { String datum = t98a.substring(7); transaction.datum_valuta = date_only_format.parse(datum); } else { System.out.println("Unbekannter 98A: " + t98a); } } String move = Swift.getTagValue(onedetail, "25D", 0); if (move != null) if (move.startsWith(":MOVE")) { if (move.endsWith("REVE")) transaction.storno = true; } else { System.out.println("Unbekannter 25D: " + move); } String freitext = Swift.getTagValue(onedetail, "70E", 0); if (freitext != null) if (freitext.startsWith(":TRDE")) { transaction.freitext_details = freitext.substring(7); } else { System.out.println("Unbekannter 70E: " + freitext); } } } int party_start = onetransaction.indexOf(":16R:SETPRTY"); if (party_start >=0) { int party_end = onetransaction.indexOf(":16S:SETPRTY", party_start); if (party_end >= 0) { String oneparty = onetransaction.substring(party_start, party_end+10); String deag = Swift.getTagValue(oneparty, "95Q", 0); if (deag != null) { transaction.gegenpartei = deag.substring(7); } } } instrument.transactions.add(transaction); trans_start = oneinstrument.indexOf(":16R:TRAN\r\n", trans_start); } entry.instruments.add(instrument); } } ((GVRWPDepotUms)jobResult).addEntry(entry); buffer.delete(0,onerecord.length()); } catch (Exception e) { throw new HBCI_Exception("*** error while extracting data",e); } } ((GVRWPDepotUms)jobResult).rest=buffer.toString(); } public void verifyConstraints() { super.verifyConstraints(); checkAccountCRC("my"); } }