///|
pub(all) enum CashFlowKind {
Operating
Investing
Financing
Unclassified
} derive(Debug, Eq)
///|
pub struct CashFlowRule {
account : String
kind : CashFlowKind
factor : Int
} derive(Debug, Eq)
///|
pub fn CashFlowRule::new(
account : String,
kind : CashFlowKind,
factor? : Int = 1,
) -> CashFlowRule {
{ account, kind, factor }
}
///|
pub struct CashFlowLine {
kind : CashFlowKind
amount : Amount
entries : Int
} derive(Debug, Eq)
///|
pub fn cash_flow(
period : String,
entries : Array[Entry],
rules : Array[CashFlowRule],
) -> Array[CashFlowLine] {
let result : Array[CashFlowLine] = []
for entry in entries {
if entry.period != period || !entry.cash {
continue
}
let rule = find_cash_rule(rules, entry.account)
let kind = match rule {
Some(value) => value.kind
None => Unclassified
}
let factor = match rule {
Some(value) => value.factor
None => 1
}
let value = (entry.debit - entry.credit) * factor
add_cash_line(result, kind, value)
}
result
}
///|
fn find_cash_rule(
rules : Array[CashFlowRule],
account : String,
) -> CashFlowRule? {
for rule in rules {
if rule.account == account {
return Some(rule)
}
}
None
}
///|
fn add_cash_line(
lines : Array[CashFlowLine],
kind : CashFlowKind,
amount : Amount,
) -> Unit {
for i, line in lines {
if line.kind == kind {
lines[i] = {
..line,
amount: line.amount + amount,
entries: line.entries + 1,
}
return
}
}
lines.push({ kind, amount, entries: 1 })
}