use crate::model::{Posting, Transaction};
use rust_decimal::Decimal;
use std::cmp::{max, Ordering};
use std::fmt::{Display, Formatter};
use tackler_api::txn_ts;
#[derive(Debug, Clone)]
pub struct RegisterPosting<'a> {
pub post: &'a Posting,
pub amount: Decimal,
}
impl<'a> Eq for RegisterPosting<'a> {}
impl<'a> PartialEq<Self> for RegisterPosting<'a> {
fn eq(&self, other: &Self) -> bool {
self.post.acctn == other.post.acctn
}
}
impl<'a> PartialOrd<Self> for RegisterPosting<'a> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'a> Ord for RegisterPosting<'a> {
fn cmp(&self, other: &Self) -> Ordering {
self.post.acctn.cmp(&other.post.acctn)
}
}
impl<'a> Display for RegisterPosting<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{} {} {}",
self.post.acctn.account, self.post.amount, self.amount
)
}
}
#[derive(Debug)]
pub(crate) struct RegisterEntry<'a> {
pub txn: &'a Transaction,
pub posts: Vec<RegisterPosting<'a>>,
}
impl<'a> Display for RegisterEntry<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let indent = " ".repeat(12);
let mut line_len = 0;
write!(
f,
"{}",
self.txn
.header
.to_string_with_indent(&indent, txn_ts::rfc_3339)
)?;
for p in &self.posts {
let line = format!(
"{}{:<33}{:>18.prec$} {:>18.prec$}{}",
indent,
p.post.acctn.account,
p.post.amount,
p.amount,
p.post
.acctn
.commodity
.as_ref()
.map_or(String::default(), |c| format!(" {}", c.name)),
prec = 2,
);
line_len = max(line_len, line.len());
writeln!(f, "{line}")?;
}
writeln!(f, "{}", "-".repeat(line_len))
}
}