use std::ops::Div; use derive_builder::Builder; use diesel::prelude::*; use serde::{Deserialize, Serialize}; use crate::{Drip, Transaction}; #[derive( Builder, Clone, Queryable, Identifiable, Selectable, Debug, PartialEq, Serialize, Deserialize, Insertable, )] #[diesel(table_name = crate::schema::buckets)] pub struct Bucket { pub id: i32, pub balance: Option, pub balance_cache_key: Option, #[diesel(column_name = "bucket_group")] pub group: String, pub name: String, } impl Bucket { pub fn is_empty(&self, drips: &[Drip], transactions: &[Transaction]) -> bool { drips.iter().all(|drip| drip.bucket_id != self.id) && transactions .iter() .all(|t| t.bucket_id.is_none_or(|id| id != self.id)) } pub fn pretty_balance_per_100(&self) -> String { let abs_balance_per_100 = self.balance.unwrap_or(0).div(100).abs(); if self.balance.is_none_or(|balance| balance >= 0) { abs_balance_per_100.to_string() } else { format!("({abs_balance_per_100})") } } }