52次发布
新 0.2.41 | 2024年8月26日 |
---|---|
0.2.40 | 2024年8月19日 |
0.2.30 | 2024年7月23日 |
0.2.25 | 2024年6月28日 |
0.1.6 | 2024年5月28日 |
#7 in #cala
1,520 每月下载量
用于 cala-server
355KB
10K SLoC
cala
运行(单元)测试
make reset-deps next-watch
运行端到端测试
make e2e
运行服务器
make run-server
lib.rs
:
cala-ledger
此crate提供了一套原语,用于实现一个兼容SQL的双式会计系统。该系统专门设计用于处理货币和构建金融产品。
访问Cala项目的网站以获取更多信息和学习教程。
快速入门
以下是初始化账簿、创建原语模板和发布交易的步骤。这是一个玩具示例,将所有组件从端到端整合在一起。不建议用于实际用途。
use cala_ledger::{account::*, journal::*, tx_template::*, *};
use rust_decimal::Decimal;
use uuid::uuid;
async fn init_cala(journal_id: JournalId) -> anyhow::Result<CalaLedger, anyhow::Error> {
let cala_config = CalaLedgerConfig::builder()
.pg_con("postgres://user:password@localhost:5432/pg")
// .exec_migrations(true) # commented out for execution in CI
.build()?;
let cala = CalaLedger::init(cala_config).await?;
// Initialize the journal - all entities are constructed via builders
let new_journal = NewJournal::builder()
.id(journal_id)
.name("Ledger")
.build()
.expect("Couldn't build NewJournal");
let _ = cala.journals().create(new_journal).await;
// Initialize an income omnibus account
let main_account_id = uuid!("00000000-0000-0000-0000-000000000001");
let new_account = NewAccount::builder()
.id(main_account_id)
.name("Income")
.code("Income")
.build()?;
cala.accounts().create(new_account).await?;
// Create the trivial 'income' template
let params = vec![
NewParamDefinition::builder()
.name("sender_account_id")
.r#type(ParamDataType::Uuid)
.build()?,
NewParamDefinition::builder()
.name("units")
.r#type(ParamDataType::Decimal)
.build()?,
];
let entries = vec![
NewTxTemplateEntry::builder()
.entry_type("'INCOME_DR'")
.account_id("params.sender_account_id")
.layer("SETTLED")
.direction("DEBIT")
.units("params.units")
.currency("'BTC'")
.build()?,
NewTxTemplateEntry::builder()
.entry_type("'INCOME_CR'")
.account_id(format!("uuid('{}')", main_account_id))
.layer("SETTLED")
.direction("CREDIT")
.units("params.units")
.currency("'BTC'")
.build()?,
];
let tx_code = "GENERAL_INCOME";
let new_template = NewTxTemplate::builder()
.id(uuid::Uuid::new_v4())
.code(tx_code)
.params(params)
.transaction(
NewTxTemplateTransaction::builder()
.effective("date()")
.journal_id(format!("uuid('{}')", journal_id))
.build()?,
)
.entries(entries)
.build()?;
cala.tx_templates().create(new_template).await?;
Ok(cala)
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let journal_id = JournalId::from(uuid!("00000000-0000-0000-0000-000000000001"));
let cala = init_cala(journal_id).await?;
// The account that is sending to the general income account
let sender_account_id = AccountId::new();
let sender_account = NewAccount::builder()
.id(sender_account_id)
.name(format!("Sender-{}", sender_account_id))
.code(format!("Sender-{}", sender_account_id))
.build()?;
cala.accounts().create(sender_account).await?;
// Prepare the input parameters that the template requires
let mut params = Params::new();
params.insert("sender_account_id", sender_account_id);
params.insert("units", Decimal::ONE);
// Create the transaction via the template
cala.post_transaction(TransactionId::new(), "GENERAL_INCOME", params)
.await?;
let account_balance = cala
.balances()
.find(journal_id, sender_account_id, "BTC".parse()?)
.await?;
let expected_balance = Decimal::new(-1, 0); // Define the expected balance
assert_eq!(account_balance.settled(), expected_balance);
Ok(())
}
依赖项
~49–69MB
~1M SLoC