# tktax-budgeting
**tktax-budgeting** is a Rust library in the tktax ecosystem providing structures and traits for budget management and transaction category comparisons. It enables users to:
- Define budgets on monthly, quarterly, or annual time horizons.
- Compare actual expenditures or credits to budgeted amounts per category.
- Employ strongly-typed domain models with robust error handling (no stringly-typed errors).
## Features
1. **`Budget<TxCat>`**
- Stores monthly category amounts and default allocations.
- Built using [`derive_builder`](https://docs.rs/derive_builder/latest/derive_builder/), allowing for flexible initialization.
- Methods for dynamically setting or removing category budgets without re-instantiation.
2. **`BudgetComparison<TxCat>`**
- Summarizes per-category actual vs. budgeted values, including a variance measurement.
3. **`Budgeting<TxCat>` Trait**
- Facilitates budget-to-actual comparisons for a domain `Account`.
- Offers both per-month and aggregate-based comparison methods.
4. **Time Period Abstractions**
- `BudgetTimePeriod` enumerates supported intervals (Monthly, Quarterly, Annual).
5. **Error Handling**
- `BudgetError` covers domain-specific error conditions without resorting to textual messages.
## Usage
Add the following to your `Cargo.toml`:
```toml
[dependencies]
tktax-budgeting = "0.1.0"
```
### Example
```rust
use tktax_budgeting::{
BudgetBuilder, Budget, Budgeting, BudgetTimePeriod,
BudgetComparison, BudgetError,
};
use tktax_account::Account;
use tktax_money::MonetaryAmount;
use tktax_transaction_category::TransactionCategory;
use std::collections::HashMap;
// Custom transaction category for illustration:
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum MyCategory {
Dining,
Groceries,
Rent,
}
// Implement the TransactionCategory trait:
impl TransactionCategory for MyCategory {}
// Construct a budget:
let mut monthly_budgets = HashMap::new();
monthly_budgets.insert(MyCategory::Dining, MonetaryAmount::from(200));
monthly_budgets.insert(MyCategory::Groceries, MonetaryAmount::from(300));
monthly_budgets.insert(MyCategory::Rent, MonetaryAmount::from(800));
let budget = BudgetBuilder::<MyCategory>::default()
.monthly_category_budgets(monthly_budgets)
.default_monthly_budget(MonetaryAmount::from(50))
.time_period(BudgetTimePeriod::Monthly)
.build()
.map_err(|_| BudgetError::IncompleteBuilder)?;
// Suppose we already have an Account populated with transactions:
let my_account = Account::empty(); // your domain logic populates it
// We also have a category map, or a function to map transactions to MyCategory:
let category_map = /* your domain CategoryMap<MyCategory> */;
// Compare actual amounts to budget:
let comps = my_account.compare_actual_to_budget_monthly(&budget, &category_map);
for comparison in comps {
println!(
"Category: {:?}, Budgeted: {}, Actual: {}, Variance: {}",
comparison.category(),
comparison.budgeted(),
comparison.actual(),
comparison.variance()
);
}
```
## Testing
The library contains a suite of unit tests demonstrating the usage patterns:
- Verifying the `Budget` builder defaults and field assignments.
- Checking dynamic category budget addition and removal.
- Confirming correct computation of variances.
To run tests:
```bash
cargo test
```
## Contributing
Contributions or issues can be reported at the [project repository](https://github.com/klebs6/tktax).
## License
This project is licensed under the [MIT license](LICENSE).