Skip to main content

stateset_embedded/
gift_cards.rs

1//! Gift card operations for issuing, charging, and refunding gift cards
2//!
3//! # Example
4//!
5//! ```rust,ignore
6//! use stateset_embedded::{Commerce, CreateGiftCard, CustomerId};
7//! use rust_decimal_macros::dec;
8//!
9//! let commerce = Commerce::new("./store.db")?;
10//!
11//! let gift_card = commerce.gift_cards().create(CreateGiftCard {
12//!     initial_balance: dec!(50.00),
13//!     customer_id: Some(CustomerId::new()),
14//!     ..Default::default()
15//! })?;
16//!
17//! println!("Gift card code: {}", gift_card.code);
18//! # Ok::<(), stateset_embedded::CommerceError>(())
19//! ```
20
21use rust_decimal::Decimal;
22use stateset_core::{
23    CreateGiftCard, GiftCard, GiftCardFilter, GiftCardId, GiftCardTransaction, Result,
24    UpdateGiftCard,
25};
26use stateset_db::{Database, DatabaseCapability};
27use std::sync::Arc;
28
29/// Gift card operations for issuing, charging, and refunding.
30pub struct GiftCards {
31    db: Arc<dyn Database>,
32}
33
34impl std::fmt::Debug for GiftCards {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        f.debug_struct("GiftCards").finish_non_exhaustive()
37    }
38}
39
40impl GiftCards {
41    pub(crate) fn new(db: Arc<dyn Database>) -> Self {
42        Self { db }
43    }
44
45    /// Whether gift cards are supported by the active backend.
46    #[must_use]
47    pub fn is_supported(&self) -> bool {
48        self.db.supports_capability(DatabaseCapability::GiftCards)
49    }
50
51    fn ensure_supported(&self) -> Result<()> {
52        self.db.ensure_capability(DatabaseCapability::GiftCards)
53    }
54
55    /// Create a new gift card.
56    ///
57    /// # Example
58    ///
59    /// ```rust,ignore
60    /// use stateset_embedded::{Commerce, CreateGiftCard, CustomerId};
61    /// use rust_decimal_macros::dec;
62    ///
63    /// let commerce = Commerce::new("./store.db")?;
64    ///
65    /// let gift_card = commerce.gift_cards().create(CreateGiftCard {
66    ///     initial_balance: dec!(100.00),
67    ///     customer_id: Some(CustomerId::new()),
68    ///     ..Default::default()
69    /// })?;
70    /// # Ok::<(), stateset_embedded::CommerceError>(())
71    /// ```
72    pub fn create(&self, input: CreateGiftCard) -> Result<GiftCard> {
73        self.ensure_supported()?;
74        self.db.gift_cards().create(input)
75    }
76
77    /// Get a gift card by ID.
78    pub fn get(&self, id: GiftCardId) -> Result<Option<GiftCard>> {
79        self.ensure_supported()?;
80        self.db.gift_cards().get(id)
81    }
82
83    /// Get a gift card by its unique code.
84    pub fn get_by_code(&self, code: &str) -> Result<Option<GiftCard>> {
85        self.ensure_supported()?;
86        self.db.gift_cards().get_by_code(code)
87    }
88
89    /// Update a gift card.
90    pub fn update(&self, id: GiftCardId, input: UpdateGiftCard) -> Result<GiftCard> {
91        self.ensure_supported()?;
92        self.db.gift_cards().update(id, input)
93    }
94
95    /// List gift cards with optional filtering.
96    pub fn list(&self, filter: GiftCardFilter) -> Result<Vec<GiftCard>> {
97        self.ensure_supported()?;
98        self.db.gift_cards().list(filter)
99    }
100
101    /// Charge (debit) a gift card.
102    ///
103    /// Reduces the gift card balance by the specified amount.
104    pub fn charge(
105        &self,
106        id: GiftCardId,
107        amount: Decimal,
108        reference_id: Option<String>,
109    ) -> Result<GiftCardTransaction> {
110        self.ensure_supported()?;
111        self.db.gift_cards().charge(id, amount, reference_id)
112    }
113
114    /// Refund (credit) to a gift card.
115    ///
116    /// Increases the gift card balance by the specified amount.
117    pub fn refund(
118        &self,
119        id: GiftCardId,
120        amount: Decimal,
121        reference_id: Option<String>,
122    ) -> Result<GiftCardTransaction> {
123        self.ensure_supported()?;
124        self.db.gift_cards().refund(id, amount, reference_id)
125    }
126
127    /// Disable a gift card so it can no longer be used.
128    pub fn disable(&self, id: GiftCardId) -> Result<GiftCard> {
129        self.ensure_supported()?;
130        self.db.gift_cards().disable(id)
131    }
132
133    /// Get transaction history for a gift card.
134    pub fn get_transactions(&self, gift_card_id: GiftCardId) -> Result<Vec<GiftCardTransaction>> {
135        self.ensure_supported()?;
136        self.db.gift_cards().get_transactions(gift_card_id)
137    }
138}