14 个版本 (7 个破坏性)
0.8.2 | 2020年6月27日 |
---|---|
0.7.1 | 2020年5月11日 |
0.6.0 | 2020年3月22日 |
#166 在 金融
每月下载量 38
62KB
1K SLoC
Doublecount
一个用于 Rust 的双重记账系统/库。
该项目深受 beancount 启发,但当前提供了一个更简单的模型。它已被设计为嵌入到其他应用程序中以运行会计计算。
系统中的商品使用由 commodity 库提供的原语表示,而 rust_decimal 为其提供支持。
这个库正在积极开发中,但应该已经可以用于一些简单用途。未来可能会进行一些 API 变更,以便将事务/操作流式传输到系统中,并支持并行计算事务,以允许大型程序在多核计算机上高效执行。
可选功能
以下功能可以启用以提供额外功能
serde-support
- 启用通过
serde
进行序列化/反序列化的支持
- 启用通过
用法
use doublecount::{
AccountStatus, EditAccountStatus, Account, Program, Action,
ProgramState, Transaction, TransactionElement, BalanceAssertion,
ActionTypeValue,
};
use commodity::{CommodityType, Commodity};
use chrono::NaiveDate;
use std::rc::Rc;
use std::str::FromStr;
// create a commodity from a currency's iso4317 alphanumeric code
let aud = Rc::from(CommodityType::from_str("AUD", "Australian Dollar").unwrap());
// Create a couple of accounts
let account1 = Rc::from(Account::new_with_id(Some("Account 1"), aud.id, None));
let account2 = Rc::from(Account::new_with_id(Some("Account 2"), aud.id, None));
// create a new program state, with accounts starting Closed
let mut program_state = ProgramState::new(
&vec![account1.clone(), account2.clone()],
AccountStatus::Closed
);
// open account1
let open_account1 = EditAccountStatus::new(
account1.id,
AccountStatus::Open,
NaiveDate::from_str("2020-01-01").unwrap(),
);
// open account2
let open_account2 = EditAccountStatus::new(
account2.id,
AccountStatus::Open,
NaiveDate::from_str("2020-01-01").unwrap(),
);
// create a transaction to transfer some commodity
// from account1 to account2.
let transaction1 = Transaction::new(
Some(String::from("Transaction 1")),
NaiveDate::from_str("2020-01-02").unwrap(),
vec![
TransactionElement::new(
account1.id,
Some(Commodity::from_str("-2.52 AUD").unwrap()),
None,
),
TransactionElement::new(
account2.id,
Some(Commodity::from_str("2.52 AUD").unwrap()),
None,
),
],
);
// create a balance assertion (that will cause the program to return an error
// if it fails), to check that the balance of account1 matches the expected
// value of -1.52 AUD at the start of the date of 2020-01-03
let balance_assertion1 = BalanceAssertion::new(
account1.id,
NaiveDate::from_str("2020-01-03").unwrap(),
Commodity::from_str("-2.52 AUD").unwrap()
);
// create another transaction to transfer commodity from
// account2 to account1, using the simpler syntax.
let transaction2 = Transaction::new_simple(
Some("Transaction 2"),
NaiveDate::from_str("2020-01-03").unwrap(),
account2.id,
account1.id,
Commodity::from_str("1.0 AUD").unwrap(),
None,
);
let balance_assertion2 = BalanceAssertion::new(
account1.id,
NaiveDate::from_str("2020-01-04").unwrap(),
Commodity::from_str("-1.52 AUD").unwrap()
);
let balance_assertion3 = BalanceAssertion::new(
account2.id,
NaiveDate::from_str("2020-01-04").unwrap(),
Commodity::from_str("1.52 AUD").unwrap()
);
let actions: Vec<Rc<ActionTypeValue>> = vec![
Rc::new(open_account1.into()),
Rc::new(open_account2.into()),
Rc::new(transaction1.into()),
Rc::new(balance_assertion1.into()),
Rc::new(transaction2.into()),
Rc::new(balance_assertion2.into()),
Rc::new(balance_assertion3.into()),
];
// create a program from the actions
let program = Program::new(actions);
// run the program
program_state.execute_program(&program).unwrap();
依赖关系
~2.3–3.5MB
~57K SLoC