Skip to main content

stateset_embedded/
store_credits.rs

1//! Store credit operations for managing customer store credit balances
2//!
3//! # Example
4//!
5//! ```rust,ignore
6//! use stateset_embedded::{Commerce, CreateStoreCredit, CustomerId, StoreCreditReason};
7//! use rust_decimal_macros::dec;
8//!
9//! let commerce = Commerce::new("./store.db")?;
10//!
11//! let credit = commerce.store_credits().create(CreateStoreCredit {
12//!     customer_id: CustomerId::new(),
13//!     initial_balance: dec!(25.00),
14//!     reason: StoreCreditReason::ReturnRefund,
15//!     ..Default::default()
16//! })?;
17//!
18//! println!("Store credit balance: ${}", credit.current_balance);
19//! # Ok::<(), stateset_embedded::CommerceError>(())
20//! ```
21
22use rust_decimal::Decimal;
23use stateset_core::{
24    AdjustStoreCredit, CreateStoreCredit, Result, StoreCredit, StoreCreditFilter, StoreCreditId,
25    StoreCreditTransaction,
26};
27use stateset_db::{Database, DatabaseCapability};
28use std::sync::Arc;
29
30/// Store credit operations for managing customer balances.
31pub struct StoreCredits {
32    db: Arc<dyn Database>,
33}
34
35impl std::fmt::Debug for StoreCredits {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        f.debug_struct("StoreCredits").finish_non_exhaustive()
38    }
39}
40
41impl StoreCredits {
42    pub(crate) fn new(db: Arc<dyn Database>) -> Self {
43        Self { db }
44    }
45
46    /// Whether store credits are supported by the active backend.
47    #[must_use]
48    pub fn is_supported(&self) -> bool {
49        self.db.supports_capability(DatabaseCapability::StoreCredits)
50    }
51
52    fn ensure_supported(&self) -> Result<()> {
53        self.db.ensure_capability(DatabaseCapability::StoreCredits)
54    }
55
56    /// Create a new store credit.
57    ///
58    /// # Example
59    ///
60    /// ```rust,ignore
61    /// use stateset_embedded::{Commerce, CreateStoreCredit, CustomerId, StoreCreditReason};
62    /// use rust_decimal_macros::dec;
63    ///
64    /// let commerce = Commerce::new("./store.db")?;
65    ///
66    /// let credit = commerce.store_credits().create(CreateStoreCredit {
67    ///     customer_id: CustomerId::new(),
68    ///     initial_balance: dec!(50.00),
69    ///     reason: StoreCreditReason::GoodwillCredit,
70    ///     ..Default::default()
71    /// })?;
72    /// # Ok::<(), stateset_embedded::CommerceError>(())
73    /// ```
74    pub fn create(&self, input: CreateStoreCredit) -> Result<StoreCredit> {
75        self.ensure_supported()?;
76        self.db.store_credits().create(input)
77    }
78
79    /// Get a store credit by ID.
80    pub fn get(&self, id: StoreCreditId) -> Result<Option<StoreCredit>> {
81        self.ensure_supported()?;
82        self.db.store_credits().get(id)
83    }
84
85    /// List store credits with optional filtering.
86    pub fn list(&self, filter: StoreCreditFilter) -> Result<Vec<StoreCredit>> {
87        self.ensure_supported()?;
88        self.db.store_credits().list(filter)
89    }
90
91    /// Adjust a store credit balance.
92    ///
93    /// Can increase or decrease the balance with a reason for the adjustment.
94    pub fn adjust(&self, id: StoreCreditId, input: AdjustStoreCredit) -> Result<StoreCredit> {
95        self.ensure_supported()?;
96        self.db.store_credits().adjust(id, input)
97    }
98
99    /// Apply store credit to an order (debit).
100    ///
101    /// Reduces the store credit balance by the specified amount.
102    pub fn apply(
103        &self,
104        id: StoreCreditId,
105        amount: Decimal,
106        reference_id: Option<String>,
107    ) -> Result<StoreCreditTransaction> {
108        self.ensure_supported()?;
109        self.db.store_credits().apply(id, amount, reference_id)
110    }
111
112    /// Get transaction history for a store credit.
113    pub fn get_transactions(
114        &self,
115        store_credit_id: StoreCreditId,
116    ) -> Result<Vec<StoreCreditTransaction>> {
117        self.ensure_supported()?;
118        self.db.store_credits().get_transactions(store_credit_id)
119    }
120}