Added GetTransactions functionality for Lloyds

This commit is contained in:
AaronJamesY 2017-02-13 23:27:36 +00:00
parent 8420adb2e0
commit fe03c4484d
11 changed files with 171 additions and 3 deletions

View file

@ -27,9 +27,18 @@ namespace BankingBot.ActionManagers.AccountManagers
providerAccountManager = (IProviderAccountManager)Activator.CreateInstance(providerAccountManagerType, BrowserBot, scriptManager);
}
#region Behaviours
public IEnumerable<Account> GetAccounts()
{
return providerAccountManager.GetAccounts();
}
public IEnumerable<Transaction> GetTransactions(string accountNumber)
{
return providerAccountManager.GetTransactions(accountNumber);
}
#endregion
}
}

View file

@ -1,6 +1,7 @@
using BankingBot.Attributes;
using BankingBot.Contracts;
using BankingBot.Enums;
using BankingBot.Extensions;
using BankingBot.Models;
using BankingBot.Urls;
using OpenQA.Selenium;
@ -19,6 +20,16 @@ namespace BankingBot.ActionManagers.AccountManagers
readonly IBrowserBot browserBot;
readonly IScriptManager scriptManager;
private enum TransactionTableColumn
{
Date = 0,
Description = 1,
Type = 2,
In = 3,
Out = 4,
Balance = 5
}
public LloydsAccountManager(
IBrowserBot browserBot,
IScriptManager scriptManager)
@ -61,5 +72,70 @@ namespace BankingBot.ActionManagers.AccountManagers
return accounts;
}
public IEnumerable<Transaction> GetTransactions(string accountNumber)
{
var transactions = new List<Transaction>();
var ajaxIdentifier = GetAjaxIdentifierForAccountNumber(accountNumber);
var accountDetailsUrl = $"{LloydsUrls.AccountDetails}/{ajaxIdentifier}";
browserBot.WebDriver.Url = accountDetailsUrl;
var transactionsTableBody = browserBot.WebDriver
.FindElement(By.ClassName("statements-wrap"))
.FindElement(By.ClassName("cwa-tbody"));
var transactionRows = transactionsTableBody.FindElements(By.CssSelector("tr[aria-expanded='false']"));
foreach (var row in transactionRows)
{
var rowCells = row.FindElements(By.TagName("td"));
var transaction = new Transaction
{
Date = DateTime.Parse(rowCells[(int)TransactionTableColumn.Date].Text),
IsPending = false,
Description = rowCells[(int)TransactionTableColumn.Description].Text
};
var amountIn = rowCells[(int)TransactionTableColumn.In].Text;
var amountOut = rowCells[(int)TransactionTableColumn.Out].Text;
if (amountIn != "")
{
transaction.Amount = decimal.Parse(amountIn);
}
else
{
transaction.Amount = -(decimal.Parse(amountOut));
}
transactions.Add(transaction);
}
return transactions;
}
private string GetAjaxIdentifierForAccountNumber(string accountNumber)
{
var currentUrl = browserBot.WebDriver.Url;
browserBot.WebDriver.Url = LloydsUrls.AccountOverview;
IWebElement accountContainer = null;
var accountContainers = browserBot.WebDriver.FindElements(By.ClassName("des-m-sat-xx-account-tile"));
foreach (var cnt in accountContainers)
{
if (cnt.HasElement(By.ClassName("account-number")))
{
accountContainer = cnt;
break;
}
}
if (accountContainer == null)
throw new InvalidOperationException($"Could not find account with account number '{accountNumber}'");
return accountContainer.GetAttribute("data-ajax-identifier");
}
}
}

View file

@ -69,6 +69,7 @@
<Compile Include="Enums\ResponseStatus.cs" />
<Compile Include="Enums\TransactionType.cs" />
<Compile Include="Exceptions\InvalidCredentialsException.cs" />
<Compile Include="Extensions\IWebElementExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Helpers\AccountHelpers.cs" />
<Compile Include="LoginCredentials\BarclaysLoginCredentials.cs" />

View file

@ -58,6 +58,11 @@ namespace BankingBot
return accountManager.GetAccounts();
}
public IEnumerable<Transaction> GetTransactions(string accountNumber)
{
return accountManager.GetTransactions(accountNumber);
}
#endregion
#region IDisposable Support
@ -93,6 +98,8 @@ namespace BankingBot
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}

View file

@ -7,6 +7,9 @@ namespace BankingBot.Contracts
public interface IAccountManager
{
void Init(Provider provider);
IEnumerable<Account> GetAccounts();
IEnumerable<Transaction> GetTransactions(string accountNumber);
}
}

View file

@ -10,5 +10,7 @@ namespace BankingBot.Contracts
decimal GetBalance();
IEnumerable<Account> GetAccounts();
IEnumerable<Transaction> GetTransactions(string accountNumber);
}
}

View file

@ -10,5 +10,7 @@ namespace BankingBot.Contracts
public interface IProviderAccountManager
{
IEnumerable<Account> GetAccounts();
IEnumerable<Transaction> GetTransactions(string accountNumber);
}
}

View file

@ -8,5 +8,47 @@ namespace BankingBot.Enums
{
public enum TransactionType
{
BGC,
BNS,
BP,
CHG,
CHQ,
COM,
COR,
CPT,
CSH,
CSQ,
DD,
DEB,
DEP,
EFT,
EUR,
FE,
FEE,
FPC,
FPI,
FPO,
IB,
INT,
MPI,
MPO,
MTG,
NS,
NSC,
OTH,
PAY,
PSB,
PSV,
SAL,
SPB,
SO,
STK,
TD,
TDG,
TDI,
TDN,
TFR,
UT,
SUR
}
}
}

View file

@ -0,0 +1,25 @@
using OpenQA.Selenium;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankingBot.Extensions
{
public static class IWebElementExtensions
{
public static bool HasElement(this IWebElement element, By by)
{
try
{
element.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
}
}

View file

@ -5,8 +5,6 @@ namespace BankingBot.Models
{
public class Transaction
{
public Account Account { get; set; }
public decimal Amount { get; set; }
public TransactionType Type { get; set; }
@ -14,5 +12,7 @@ namespace BankingBot.Models
public string Description { get; set; }
public DateTime Date { get; set; }
public bool IsPending { get; set; }
}
}

View file

@ -5,5 +5,6 @@
public const string Login = "https://online.lloydsbank.co.uk/personal/logon/login.jsp";
public const string MemorableInfo = "https://secure.lloydsbank.co.uk/personal/a/logon/entermemorableinformation.jsp";
public const string AccountOverview = "https://secure.lloydsbank.co.uk/personal/a/account_overview_personal/";
public const string AccountDetails = "https://secure.lloydsbank.co.uk/personal/a/account_details_ress";
}
}