public void ImportFile() { TCAMTParser p = new TCAMTParser(); p.ProcessFile("../../csharp/ICT/Petra/Plugins/BankimportCAMT/Testing/test-data/test1.xml"); Console.WriteLine("Number of statements: " + p.statements.Count.ToString()); foreach (TStatement stmt in p.statements) { Console.WriteLine("Number of transaction: " + stmt.transactions.Count.ToString()); foreach (TTransaction tr in stmt.transactions) { Console.WriteLine(tr.valueDate.ToShortDateString()); } } }
/// check for xml files in RawCAMT.Path /// there are files from several banks, possibly for several legal entities /// one file can contain several bank statements from several days /// split the files into one file per statement, and move the file to a separate directory for each legal entity private bool SplitFilesAndMove() { if (!TAppSettingsManager.HasValue("BankAccounts")) { TLogging.Log("missing parameter BankAccounts in config file"); return false; } // BankAccounts contains a comma separated list of bank accounts, // each with bank account number, bank id, name for legal entity string[] bankAccountData = TAppSettingsManager.GetValue("BankAccounts").Split(new char[] { ',' }); string RawPath = TAppSettingsManager.GetValue("RawCAMT.Path"); string OutputPath = TAppSettingsManager.GetValue("CAMT.Output.Path"); string[] RawXMLFiles = Directory.GetFiles(RawPath, "*.xml"); CreateDirectories(OutputPath, bankAccountData); foreach (string RawFile in RawXMLFiles) { // 2015-11-02_C53_DE12500105170648489890_EUR_X000XX.xml string RawFileName = Path.GetFileName(RawFile); if (!RawFileName.Contains("_C53_") || (RawFileName.Length < "2015-11-02_C53_DE12500105170648489890_EUR".Length)) { continue; } TLogging.Log("BankImport CAMT plugin: moving file " + RawFile); string IBAN = RawFileName.Substring("2015-11-02_C53_".Length, "DE12500105170648489890".Length); string[] DateString = RawFileName.Substring(0, "2015-11-02".Length).Split(new char[] { '-' }); DateTime stmtDate = new DateTime(Convert.ToInt32(DateString[0]), Convert.ToInt32(DateString[1]), Convert.ToInt32(DateString[2])); bool severalYears = false; // it seems we cannot rely on the filename for the date. therefore we need to parse the file TCAMTParser parser = new TCAMTParser(); parser.ProcessFile(RawFile); foreach (TStatement stmt in parser.statements) { stmtDate = stmt.date; severalYears = stmt.severalYears; // currently assuming that there is only one statement per file break; } for (Int32 bankCounter = 0; bankCounter < bankAccountData.Length / 3; bankCounter++) { if (IBAN.EndsWith(bankAccountData[bankCounter * 3 + 0])) { string newfilename = OutputPath + Path.DirectorySeparatorChar + bankAccountData[bankCounter * 3 + 2] + Path.DirectorySeparatorChar + bankAccountData[bankCounter * 3 + 1] + "_" + stmtDate.ToString("yyMMdd") + ".xml"; if (File.Exists(newfilename)) { File.Delete(newfilename); } File.Move(RawFile, newfilename); // special case: one statement with transactions in two different years if (severalYears) { string prevYearFilename = OutputPath + Path.DirectorySeparatorChar + bankAccountData[bankCounter * 3 + 2] + Path.DirectorySeparatorChar + bankAccountData[bankCounter * 3 + 1] + "_" + new DateTime(stmtDate.Year - 1, 12, 31).ToString("yyMMdd") + ".xml"; if (File.Exists(prevYearFilename)) { File.Delete(prevYearFilename); } File.Copy(newfilename, prevYearFilename); } } } } return true; }
/// <summary> /// open the file and return a typed datatable /// </summary> private bool ImportFromFile(string AFilename, string ABankAccountCode, ref BankImportTDS AMainDS) { TCAMTParser parser = new TCAMTParser(); parser.ProcessFile(AFilename); Int32 statementCounter = AMainDS.AEpStatement.Rows.Count; foreach (TStatement stmt in parser.statements) { Int32 transactionCounter = 0; foreach (TTransaction tr in stmt.transactions) { BankImportTDSAEpTransactionRow row = AMainDS.AEpTransaction.NewRowTyped(); row.StatementKey = (statementCounter + 1) * -1; row.Order = transactionCounter; row.DetailKey = -1; row.AccountName = tr.partnerName; if ((tr.accountCode != null) && Regex.IsMatch(tr.accountCode, "^[A-Z]")) { // this is an iban row.Iban = tr.accountCode; row.Bic = tr.bankCode; row.BranchCode = tr.accountCode.Substring(4, 8).TrimStart(new char[] { '0' }); row.BankAccountNumber = tr.accountCode.Substring(12).TrimStart(new char[] { '0' }); } else if (tr.accountCode != null) { row.BankAccountNumber = tr.accountCode.TrimStart(new char[] { '0' }); row.BranchCode = tr.bankCode == null ? string.Empty : tr.bankCode.TrimStart(new char[] { '0' }); row.Iban = string.Empty; row.Bic = string.Empty; } row.DateEffective = tr.valueDate; row.TransactionAmount = tr.amount; row.Description = tr.description; row.TransactionTypeCode = tr.typecode; // see the codes: https://www.wgzbank.de/export/sites/wgzbank/de/wgzbank/downloads/produkte_leistungen/firmenkunden/zv_aktuelles/Uebersicht-GVC-und-Buchungstexte-WGZ-BANK_V062015.pdf if ((row.TransactionTypeCode == "052") || (row.TransactionTypeCode == "051") || (row.TransactionTypeCode == "053") || (row.TransactionTypeCode == "067") || (row.TransactionTypeCode == "068") || (row.TransactionTypeCode == "069") || (row.TransactionTypeCode == "119") /* Einzelbuchung Spende (Purpose: CHAR) */ || (row.TransactionTypeCode == "152") /* SEPA Credit Transfer Einzelbuchung Dauerauftrag */ || (row.TransactionTypeCode == "166") /* SEPA Credit Transfer */ || (row.TransactionTypeCode == "169") /* SEPA Credit Transfer Donation */ ) { // only incoming money is a potential gift if (row.TransactionAmount > 0) { row.TransactionTypeCode += MFinanceConstants.BANK_STMT_POTENTIAL_GIFT; } } AMainDS.AEpTransaction.Rows.Add(row); transactionCounter++; } AEpStatementRow epstmt = AMainDS.AEpStatement.NewRowTyped(); epstmt.StatementKey = (statementCounter + 1) * -1; epstmt.Date = stmt.date; epstmt.CurrencyCode = stmt.currency; epstmt.Filename = AFilename; epstmt.BankAccountCode = ABankAccountCode; epstmt.IdFromBank = stmt.id; if (AFilename.Length > AEpStatementTable.GetFilenameLength()) { epstmt.Filename = TAppSettingsManager.GetValue("BankNameFor" + stmt.bankCode + "/" + stmt.accountCode, stmt.bankCode + "/" + stmt.accountCode, true); } epstmt.StartBalance = stmt.startBalance; epstmt.EndBalance = stmt.endBalance; AMainDS.AEpStatement.Rows.Add(epstmt); // sort by amount, and by accountname; this is the order of the paper statements and attachments AMainDS.AEpTransaction.DefaultView.Sort = BankImportTDSAEpTransactionTable.GetTransactionAmountDBName() + "," + BankImportTDSAEpTransactionTable.GetOrderDBName(); AMainDS.AEpTransaction.DefaultView.RowFilter = BankImportTDSAEpTransactionTable.GetStatementKeyDBName() + "=" + epstmt.StatementKey.ToString(); // starting with the most negative amount, which should be the last in the order on the statement Int32 countOrderOnStatement = AMainDS.AEpTransaction.DefaultView.Count; bool countingNegative = true; foreach (DataRowView rv in AMainDS.AEpTransaction.DefaultView) { BankImportTDSAEpTransactionRow row = (BankImportTDSAEpTransactionRow)rv.Row; if ((row.TransactionAmount > 0) && countingNegative) { countingNegative = false; countOrderOnStatement = 1; } if (countingNegative) { row.NumberOnPaperStatement = countOrderOnStatement; countOrderOnStatement--; } else { row.NumberOnPaperStatement = countOrderOnStatement; countOrderOnStatement++; } } statementCounter++; } return true; }