use crate::options::Options;
use crate::requests::Requests;
use chrono::{DateTime, Utc};
use log::debug;
use serde::{Deserialize, Serialize};
use std::error::Error;
#[derive(Deserialize, Debug)]
pub struct Link {
pub href: String,
}
#[derive(Deserialize, Debug)]
pub struct Account {
#[serde(rename = "accountId")]
pub account_id: String,
pub name: String,
pub nickname: Option<String>,
pub balance: Option<f64>,
pub currency: String,
#[serde(rename = "identifierScheme")]
pub identifier_scheme: String,
pub identifier: String,
#[serde(rename = "servicerScheme")]
pub servicer_scheme: String,
#[serde(rename = "servicerIdentifier")]
pub servicer_identifier: String,
}
#[derive(Deserialize, Debug)]
pub struct AccountList {
pub accounts: Vec<Account>,
}
#[derive(Serialize, Debug, Default)]
pub struct TransactionParams {
#[serde(rename = "fromBookingDateTime")]
pub from_booking_datetime: Option<DateTime<Utc>>,
#[serde(rename = "toBookingDateTime")]
pub to_booking_datetime: Option<DateTime<Utc>>,
#[serde(rename = "pageSize")]
pub page_size: Option<u32>,
#[serde(rename = "forwardPagingToken")]
pub forward_paging_token: Option<String>,
}
impl TransactionParams {
pub fn with_from_booking_datetime(mut self, datetime: DateTime<Utc>) -> Self {
self.from_booking_datetime = Some(datetime);
self
}
pub fn with_to_booking_datetime(mut self, datetime: DateTime<Utc>) -> Self {
self.to_booking_datetime = Some(datetime);
self
}
pub fn with_page_size(mut self, page_size: u32) -> Self {
self.page_size = Some(page_size);
self
}
pub fn with_forward_paging_token(mut self, token: String) -> Self {
self.forward_paging_token = Some(token);
self
}
}
#[derive(Deserialize, Debug)]
pub struct TransactionParty {
#[serde(rename = "accountIdentifierType")]
pub account_identifier_type: String,
#[serde(rename = "accountName")]
pub account_name: String,
#[serde(rename = "accountIdentifier")]
pub account_identifier: String,
#[serde(rename = "servicerIdentifier")]
pub servicer_identifier: String,
#[serde(rename = "servicerIdentifierType")]
pub servicer_identifier_type: String,
}
#[derive(Deserialize, Debug)]
pub struct Transaction {
#[serde(rename = "transactionId")]
pub transaction_id: String,
#[serde(rename = "accountId")]
pub account_id: String,
#[serde(rename = "archiveId")]
pub archive_id: Option<String>,
pub reference: Option<String>,
pub message: Option<String>,
pub amount: String,
pub currency: String,
#[serde(rename = "creditDebitIndicator")]
pub credit_debit_indicator: String,
#[serde(rename = "accountBalance")]
pub account_balance: String,
pub creditor: Option<TransactionParty>,
pub debtor: Option<TransactionParty>,
#[serde(rename = "bookingDateTime")]
pub booking_datetime: DateTime<Utc>,
#[serde(rename = "valueDateTime")]
pub value_datetaime: DateTime<Utc>,
pub status: Option<String>,
#[serde(rename = "isoTransactionCode")]
pub iso_transaction_code: Option<String>,
#[serde(rename = "opTransactionCode")]
pub op_transaction_code: Option<String>,
}
#[derive(Deserialize, Debug)]
pub struct TransactionListLinks {
pub next: Option<Link>,
}
#[derive(Deserialize, Debug)]
pub struct TransactionList {
pub transactions: Vec<Transaction>,
#[serde(rename = "_links")]
pub links: TransactionListLinks,
}
pub struct Accounts {
options: Options,
}
impl Accounts {
pub fn new(options: Options) -> Accounts {
Accounts { options }
}
pub async fn accounts(&self) -> Result<AccountList, Box<dyn Error>> {
let url = format!("/accounts/{}/accounts", self.options.version());
let response = Requests::get(&self.options, &url, None::<()>).await?;
debug!("Accounts response: {:#?}", response);
let accounts: AccountList = response.json().await?;
Ok(accounts)
}
pub async fn account(&self, account_id: String) -> Result<Account, Box<dyn Error>> {
let url = format!(
"/accounts/{}/accounts/{}",
self.options.version(),
account_id
);
let response = Requests::get(&self.options, &url, None::<()>).await?;
debug!("Account response: {:#?}", response);
let account: Account = response.json().await?;
Ok(account)
}
pub async fn transactions(
&self,
account_id: String,
params: Option<TransactionParams>,
) -> Result<TransactionList, Box<dyn Error>> {
let url = format!(
"/accounts/{}/accounts/{}/transactions",
self.options.version(),
account_id
);
let response = Requests::get(&self.options, &url, params).await?;
debug!("Transactions response: {:#?}", response);
let list: TransactionList = response.json().await?;
Ok(list)
}
}