public List <Transaction> MapOfxToTransaction(OFX ofx) { int c = 0; List <Transaction> lstTransaction = new List <Transaction>(); //Cada item é uma transação foreach (var item in ofx.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST.Items) { Transaction transaction = new Transaction(); transaction.Account = new Account(); transaction.Account.AccountId = ofx.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKACCTFROM.ACCTID; transaction.Account.AccountType = ofx.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKACCTFROM.ACCTTYPE; transaction.Account.BankId = ofx.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKACCTFROM.BANKID; if (!String.IsNullOrWhiteSpace(item.DTPOSTED)) { string data = item.DTPOSTED.Remove(12); string dataFormatada = data.Substring(0, 4) + "-" + data.Substring(4, 2) + "-" + data.Substring(6, 2) + " " + data.Substring(8, 2) + ":" + data.Substring(10, 2); transaction.DataPost = Convert.ToDateTime(dataFormatada); } transaction.TransactionId = DateTime.Now.Day.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Year.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + c.ToString(); transaction.Memo = item.MEMO; if (!String.IsNullOrWhiteSpace(item.TRNAMT)) { transaction.Valor = Util.FormatarValorMonetario(item.TRNAMT); } lstTransaction.Add(transaction); c++; } return(lstTransaction); }
/// <summary> /// Parses the ofx payload to get account information. /// </summary> /// <param name="ofxPayload">The ofx payload.</param> /// <returns>Array of accounts.</returns> public static IEnumerable <Account> Parse(OFX ofxPayload) { var messageSet = ofxPayload.Items.FirstOrDefault(_ => _ is SignupResponseMessageSetV1) as SignupResponseMessageSetV1; var accountsResponse = messageSet?.Items.FirstOrDefault(_ => _ is AccountInfoTransactionResponse) as AccountInfoTransactionResponse; if (accountsResponse?.ACCTINFORS?.ACCTINFO == null) { yield break; } foreach (var accountInfoWrap in accountsResponse.ACCTINFORS?.ACCTINFO) { foreach (var accountInfo in accountInfoWrap.Items) { switch (accountInfo) { case CreditCardAccountInfo cc: yield return(ParseCreditCardAccount(cc)); break; case BankAccountInfo bank: yield return(ParseBankAccount(bank)); break; default: continue; } } } }
public async Task <List <STMTTRN> > RemoveTranDuplicates(OFX ofx) { var STMTTRNBase = new List <STMTTRN>(); foreach (var stm in ofx.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST.STMTTRN) { var id = stm.Id; if (id == null || id == string.Empty) { var inputStm = $"{stm.TRNTYPE.ToUpper().Replace(" ", string.Empty)}" + $"{stm.DTPOSTED.ToUpper().Replace(" ", string.Empty)}" + $"{stm.TRNAMT}" + $"{stm.MEMO.ToUpper().Replace(" ", string.Empty)}"; id = inputStm.GetHash(); } if (await _OFXRepository.GetTransactionById(id, ofx.AccountId) == null && !STMTTRNBase.Any(s => s.Id == id && s.AccountId == ofx.AccountId)) { STMTTRNBase.Add(new STMTTRN { AccountId = ofx.AccountId, Id = id, DTPOSTED = stm.DTPOSTED, MEMO = stm.MEMO, OFXId = ofx.Id, TRNAMT = stm.TRNAMT, TRNTYPE = stm.TRNTYPE }); } } return(STMTTRNBase); }
/// <summary> /// Serializes the model. /// </summary> /// <param name="model">The model.</param> /// <returns> /// Serialized representation. /// </returns> public override string Serialize(OFX model) { var xml = SerializeInternal(model); var sgml = Regex.Replace(xml, @"<([A-Za-z0-9_\-\.]+)>([^<]+)</([A-Za-z0-9_\-\.]+)>", "<$1>$2"); var result = Regex.Replace(sgml, @"<[A-Za-z0-9_\-]+ />", string.Empty); return(string.Join("\n", string.Join("\n", _default102Headers), string.Empty, result)); }
internal string PrepareOfxRequest(params IRequestBuilder[] builders) { var ofxRequest = new OFX() { Items = builders.Select(_ => _.Build()).ToArray() }; var content = _serializer.Serialize(ofxRequest); return(content); }
internal string PrepareOfxRequest(IRequestBuilder authBuilder, AbstractTopLevelMessageSet messageSet) { var authMessage = authBuilder.Build(); var ofxRequest = new OFX { Items = new[] { authMessage, messageSet } }; var content = _serializer.Serialize(ofxRequest); return(content); }
public void SalvarDadosTransaction() { TransactionDalc trsDalc = new TransactionDalc(); Maps map = new Maps(); XmlTransactions xmlTran = new XmlTransactions(); OFX ofx = xmlTran.DesserializeXml(); List <Transaction> trs = new List <Transaction>(); trs = map.MapOfxToTransaction(ofx); trsDalc.SalvarTransacoes(trs); }
async Task <TResponseMessage> ExecuteRequest <TRequestMessage, TResponseMessage>(TRequestMessage accountListRequest) where TRequestMessage : AbstractRequestMessageSet where TResponseMessage : AbstractResponseMessageSet { var request = CreatedRequest(); request.Add(accountListRequest); var ofxRequest = new OFX() { Items = request.ToArray() }; var requestBody = _serializer.Serialize(ofxRequest); if (requestBody == null) { throw new OfxSerializationException("Request serialization error."); } var responseBody = await _transport.PostRequest(Options.ApiUrl, requestBody); var ofxResponse = _serializer.Deserialize(responseBody); if (ofxResponse == null) { throw new OfxSerializationException("Response deserialization error."); } var signInResponse = ofxResponse.Items.FirstOrDefault(_ => _ is SignonResponseMessageSetV1) as SignonResponseMessageSetV1; if (signInResponse == null) { throw new OfxResponseException("SIGNONRESPONSEMESSAGESETV1 is not present in response."); } if (signInResponse.SONRS.STATUS.CODE != "0") { throw new OfxResponseException(signInResponse.SONRS.STATUS.MESSAGE); } var messageSet = ofxResponse.Items.FirstOrDefault(_ => _ is TResponseMessage) as TResponseMessage; if (messageSet == null) { throw new OfxResponseException("Requested message set " + typeof(TResponseMessage).Name.ToUpper() + " is not present in response."); } return(messageSet); }
public RegisterNewOFXCommand(OFX OFX) { base.OFX = OFX; if (OFX.Id == null || OFX.Id == string.Empty) { base.OFX.Id = OFX.GenerateOFXId(); } if (OFX.AccountId == null || OFX.AccountId == string.Empty) { base.OFX.AccountId = OFX.GenerateAccountId(); base.OFX.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKACCTFROM.Id = base.OFX.AccountId; } }
/// <summary> /// Desserializa o XML Salvo /// </summary> /// <returns></returns> public OFX DesserializeXml() { CreateNewXml(); string[] files = Directory.GetFiles(Util.Diretorio("DiretorioXml")); OFX ofx = new OFX(); FinanceTransaction tran = new FinanceTransaction(); foreach (string file in files) { ofx = Serialize.Deserialize(ofx, file); File.Copy(file, Util.Diretorio("DiretorioXmlLog") + "\\" + Path.GetFileName(file), true); File.Delete(file); return(ofx); } return(null); }
public async Task <IActionResult> Delete(List <IFormFile> files) { List <ValidationResult> validationsResults = new List <ValidationResult>(); foreach (var file in files) { var arrayFile = OFXUtils.ReadAsArray(file); var result = OFXUtils.ReadOFXtoXMLFromArray(arrayFile); var ofx = OFX.GetOFXFromString(result); ofx.Id = ofx.GenerateOFXId(); validationsResults.Add(await _OFXAppService.Remove(ofx.Id)); } return(!ModelState.IsValid ? CustomResponse(ModelState) : CustomResponse(validationsResults)); }
/// <summary> /// Uses <see cref="XmlSerializer"/> to serialize OFX Model into xml. /// </summary> /// <param name="request">The request.</param> /// <returns>Xml string.</returns> protected string SerializeInternal(OFX request) { var ns = new XmlSerializerNamespaces(); ns.Add(string.Empty, string.Empty); var writer = new StringWriter(); using (var xmlWriter = XmlWriter.Create(writer, new XmlWriterSettings { Indent = false, OmitXmlDeclaration = true })) _serializer.Serialize(xmlWriter, (object)request, ns); var xml = writer.ToString(); return(xml); }
/// <summary> /// Parses the specified ofx payload and converts it to statement. /// Accepts both credit card and bank OFX strings. /// </summary> /// <param name="ofxPayload">The ofx payload.</param> /// <returns>Returns parsed statement.</returns> /// <exception cref="Exception">Can't find Credit Card or Bank Statement'.</exception> public static Statement Parse(OFX ofxPayload) { foreach (var messageSet in ofxPayload.Items) { switch (messageSet) { case CreditcardResponseMessageSetV1 cc: return(ParseCreditCardStatement(cc.Items.FirstOrDefault() as CreditCardStatementTransactionResponse)); case BankResponseMessageSetV1 bank: return(ParseBankStatement(bank.Items.FirstOrDefault() as StatementTransactionResponse)); default: continue; } } throw new Exception("Can't find Credit Card or Bank Statement'"); }
public async Task <IActionResult> Put(List <IFormFile> files) { List <ValidationResult> validationsResults = new List <ValidationResult>(); foreach (var file in files) { var arrayFile = OFXUtils.ReadAsArray(file); var result = OFXUtils.ReadOFXtoXMLFromArray(arrayFile); var ofx = OFX.GetOFXFromString(result); ofx.FileOFX = string.Join('\n', result); var ofxViewModel = new OFXViewModel { OFX = ofx }; validationsResults.Add(await _OFXAppService.Update(ofxViewModel)); } return(!ModelState.IsValid ? CustomResponse(ModelState) : CustomResponse(validationsResults)); }
/// <summary> /// Merge transactions from the provided statement into the specified account /// </summary> /// <param name="account">The account into which transactions will be merged</param> /// <param name="statement">The statement containing the transactions to merge. The statement owning account ID must match the ID of the passed account.</param> public static void MergeStatementTransactionsIntoAccount(Account account, OFX.Types.Statement statement) { using (BackgroundTaskTracker.BeginTask("Processing Transactions")) { using (var dataService = new DataService()) { // Retrieve matching account from DB - we need to get an entity in the current db session var updateAccount = dataService.GetAccountById(account.AccountId); // If the account has no account ID set, set it from the imported statement if (updateAccount.FiAccountId == null) updateAccount.FiAccountId = statement.OwningAccount.AccountId; else if (updateAccount.FiAccountId != statement.OwningAccount.AccountId) { // TODO: Raise an error - this statement does not match the specified account. } // Add each transaction, and keep track of the earliest and latest dates DateTimeOffset earliestTransaction = DateTimeOffset.MaxValue; DateTimeOffset latestTransaction = DateTimeOffset.MinValue; foreach (var transaction in statement.Transactions) { // Update date of earliest and latest transaction if (earliestTransaction > transaction.PostDate) earliestTransaction = transaction.PostDate; if (latestTransaction < transaction.PostDate) latestTransaction = transaction.PostDate; // See if transaction is already in db try { var existingTransaction = updateAccount.Transactions.First(t => t.FiTransactionId == transaction.TransactionId); // Ensure amount and date of transaction match existingTransaction.Amount = transaction.Amount; existingTransaction.Date = transaction.PostDate.Date; } catch (InvalidOperationException) { // No such transaction, add entity // Create model transaction var dbTransaction = new Transaction { Amount = transaction.Amount, CategoryName = "", Date = transaction.PostDate.Date, Description = transaction.Name, FiTransactionId = transaction.TransactionId, }; updateAccount.Transactions.Add(dbTransaction); } } // Sum all transactions in the data set and ensure the balance on the date of the end of the statement matches the reported balance var dbBalance = updateAccount.Transactions.Where(t => t.Date <= latestTransaction) .Sum(t => t.Amount); if (dbBalance != statement.AccountBalance) { // Need to add or modify a filler transaction try { // Look for a pre-existing filler transaction as the transaction prior to the start of this statement var fillerTransaction = updateAccount.Transactions.Where(t => t.Date < earliestTransaction) .OrderByDescending(t => t.Date) .First(); // If this is not a balance adjustment transaction, move to creating a new transaction to adjust if (fillerTransaction.Description != "Balance Adjustment") throw new InvalidOperationException(); // An existing balance adjustment is in place. Modify; fillerTransaction.Amount += (statement.AccountBalance - dbBalance); } catch (InvalidOperationException) { // Determine date of filler - don't use a date in the future var fillerDate = (earliestTransaction - new TimeSpan(1, 0, 0, 0)).DateTime; if (fillerDate > DateTime.Now) fillerDate = DateTime.Now; // No existing balance adjustment transaction exists. Add one. var fillerTransaction = new Transaction { Amount = (statement.AccountBalance - dbBalance), CategoryName = "BALADJUST", Description = "Balance Adjustment", FiTransactionId = Guid.NewGuid().ToString(), Date = fillerDate }; updateAccount.Transactions.Add(fillerTransaction); } } } } }
/// <summary> /// Add an account to the database - Using OFX data specification /// </summary> /// <param name="account">Populated account object to add to database</param> /// <param name="financialInstitution">OFX financial institution to link in database. Will be created if necessary.</param> /// <param name="fiUser">User credentials for the financial institution</param> /// <returns>Created account</returns> public Account AddAccount(Account account, OFX.Types.FinancialInstitution financialInstitution, FinancialInstitutionUser fiUser) { // TODO: See if there's an existing FI or user with this info already // Look for existing FI entry with the same name FinancialInstitution fi; try { fi = DbContext.FinancialInstitutions.First(i => i.Name == financialInstitution.Name); } catch (Exception ex) { // Can result in InvalidOperationException or NullReferenceException depending on provider if (ex is InvalidOperationException || ex is NullReferenceException) { // FI Doesn't exist, add a new one fi = new FinancialInstitution { Name = financialInstitution.Name, OfxFinancialUnitId = financialInstitution.FinancialId, OfxOrganizationId = financialInstitution.OrganizationId, OfxUpdateUrl = financialInstitution.ServiceEndpoint.ToString() }; DbContext.FinancialInstitutions.Add(fi); } else throw; // Unhandled } // Look for existing user under this FI with same userId try { fiUser = fi.Users.First(u => u.UserId == fiUser.UserId && u.Password == fiUser.Password); } catch (Exception ex) { // Can result in InvalidOperationException or NullReferenceException depending on provider if (ex is InvalidOperationException || ex is NullReferenceException) { // User doesn't exist, add as new fi.Users.Add(fiUser); DbContext.FinancialInstitutionUsers.Add(fiUser); } else throw; // Unhandled } fiUser.Accounts.Add(account); DbContext.Accounts.Add(account); return account; }
public void TestReadXML() { var input = OFXUtils.ReadOFXtoXMLFromPath(@"D:\Rubens\Desktop\DevelopersChallenge2-master\DevelopersChallenge2-master\OFX\extrato1.ofx"); var ofx = OFX.GetOFXFromString(input); }
public void Remove(OFX OFX) { DbSet.Remove(OFX); }
/// <summary> /// Serializes the model. /// </summary> /// <param name="model">The model.</param> /// <returns> /// Serialized representation. /// </returns> public abstract string Serialize(OFX model);
/// <summary> /// Verify the provided account credentials. Raises an exception if validation fails /// </summary> /// <param name="financialInstitution">Financial institution to query</param> /// <param name="fiCredentials">Credentials for financial institution account</param> /// <returns>List of accounts</returns> public static async Task VerifyAccountCredentials(FinancialInstitution financialInstitution, OFX.Types.Credentials fiCredentials) { using (BackgroundTaskTracker.BeginTask("Verifying Credentials")) { // Convert from data model FI into OFX FI var ofxFinancialInstitition = new OFX.Types.FinancialInstitution(financialInstitution.Name, new Uri(financialInstitution.OfxUpdateUrl), financialInstitution.OfxOrganizationId, financialInstitution.OfxFinancialUnitId); var ofxService = new OFX2Service(ofxFinancialInstitition, fiCredentials); // Call list accounts to validate credentials await ofxService.ListAccounts().ConfigureAwait(false); } }
/// <summary> /// Serializes the model. /// </summary> /// <param name="model">The model.</param> /// <returns> /// Serialized representation. /// </returns> public override string Serialize(OFX model) { var xml = SerializeInternal(model); return(string.Join("\n", XmlHeader, Default211Header, xml)); }
public void Add(OFX OFX) { DbSet.Add(OFX); }
public void Update(OFX OFX) { DbSet.Update(OFX); }
/// <summary> /// Retrieve the list of accounts from a financial institution using OFX and return all accounts that are not already present in the database /// </summary> /// <param name="financialInstitution">Financial institution to query</param> /// <param name="fiCredentials">Credentials for financial institution account</param> /// <returns>List of accounts</returns> public static async Task<IEnumerable<Account>> EnumerateNewAccounts( OFX.Types.FinancialInstitution financialInstitution, OFX.Types.Credentials fiCredentials) { using (BackgroundTaskTracker.BeginTask("Retrieving Account Information")) { var ofxService = new OFX2Service(financialInstitution, fiCredentials); var accountList = new List<Account>(); var ofxAccountList = await ofxService.ListAccounts().ConfigureAwait(false); // TODO: If ofxAccountList is null, raise a more detailed exception using (var dataService = new DataService()) { foreach (var ofxAccount in ofxAccountList) { // Convert from OFX account type to db account type and encode account id AccountType accountType = AccountType.Checking; string accountId = ""; if (ofxAccount.GetType() == typeof (OFX.Types.CheckingAccount)) { accountType = AccountType.Checking; accountId = ((OFX.Types.CheckingAccount) ofxAccount).RoutingId + ":" + ofxAccount.AccountId; } else if (ofxAccount.GetType() == typeof (OFX.Types.SavingsAccount)) { accountType = AccountType.Savings; accountId = ((OFX.Types.SavingsAccount) ofxAccount).RoutingId + ":" + ofxAccount.AccountId; } else if (ofxAccount.GetType() == typeof (OFX.Types.CreditCardAccount)) { accountType = AccountType.Creditcard; accountId = ofxAccount.AccountId; } // Look for a matching account in the database if (!dataService.GetAccountByFinancialId(accountId).Any()) { // This account is not already in the DB, add to new account list accountList.Add(new Account { AccountName = accountType + ":" + ofxAccount.AccountId.Substring(ofxAccount.AccountId.Length - 4), AccountType = accountType.ToString(), Currency = "USD", FiAccountId = accountId }); } } } // Return the finalized list of new accounts return accountList; } }
public string Serialize(OFX request) { var sgml = _sgmlSerializer.Serialize(request); return(Default103Header + sgml); }