Skip to main content

stateset_embedded/commerce/
accessors.rs

1use super::Commerce;
2
3use crate::{
4    AccountsPayable, AccountsReceivable, Analytics, Backorders, Bom, Carts, CostAccounting, Credit,
5    CurrencyOps, CustomObjects, Customers, Erc8004, Fraud, Fulfillment, GeneralLedger, GiftCards,
6    Inventory, Invoices, Lots, Loyalty, Orders, Payments, Products, Promotions, PurchaseOrders,
7    Quality, Receiving, Returns, Reviews, SearchConfigs, Segments, Serials, Shipments,
8    ShippingZones, StoreCredits, Subscriptions, Tax, WarehouseOps, Warranties, Wishlists,
9    WorkOrders, X402,
10};
11
12impl Commerce {
13    /// Access order operations.
14    ///
15    /// # Example
16    ///
17    /// ```rust,ignore
18    /// use stateset_embedded::{Commerce, CreateOrder, CreateOrderItem};
19    /// use rust_decimal_macros::dec;
20    /// use uuid::Uuid;
21    ///
22    /// let commerce = Commerce::new("./store.db")?;
23    ///
24    /// let order = commerce.orders().create(CreateOrder {
25    ///     customer_id: Uuid::new_v4(),
26    ///     items: vec![CreateOrderItem {
27    ///         product_id: Uuid::new_v4(),
28    ///         sku: "SKU-001".into(),
29    ///         name: "Widget".into(),
30    ///         quantity: 2,
31    ///         unit_price: dec!(29.99),
32    ///         ..Default::default()
33    ///     }],
34    ///     ..Default::default()
35    /// })?;
36    /// # Ok::<(), stateset_embedded::CommerceError>(())
37    /// ```
38    #[must_use]
39    pub fn orders(&self) -> Orders {
40        #[cfg(feature = "events")]
41        {
42            Orders::new(self.db.clone(), self.event_system.clone(), self.metrics.clone())
43        }
44        #[cfg(not(feature = "events"))]
45        {
46            Orders::new(self.db.clone(), self.metrics.clone())
47        }
48    }
49
50    /// Access inventory operations.
51    ///
52    /// # Example
53    ///
54    /// ```rust,ignore
55    /// use stateset_embedded::{Commerce, CreateInventoryItem};
56    /// use rust_decimal_macros::dec;
57    ///
58    /// let commerce = Commerce::new("./store.db")?;
59    ///
60    /// // Create inventory item
61    /// commerce.inventory().create_item(CreateInventoryItem {
62    ///     sku: "SKU-001".into(),
63    ///     name: "Widget".into(),
64    ///     initial_quantity: Some(dec!(100)),
65    ///     ..Default::default()
66    /// })?;
67    ///
68    /// // Check stock
69    /// let stock = commerce.inventory().get_stock("SKU-001")?;
70    ///
71    /// // Adjust stock
72    /// commerce.inventory().adjust("SKU-001", dec!(-5), "Sold")?;
73    /// # Ok::<(), stateset_embedded::CommerceError>(())
74    /// ```
75    #[must_use]
76    pub fn inventory(&self) -> Inventory {
77        #[cfg(feature = "events")]
78        {
79            Inventory::new(self.db.clone(), self.event_system.clone(), self.metrics.clone())
80        }
81        #[cfg(not(feature = "events"))]
82        {
83            Inventory::new(self.db.clone(), self.metrics.clone())
84        }
85    }
86
87    /// Access customer operations.
88    ///
89    /// # Example
90    ///
91    /// ```rust,ignore
92    /// use stateset_embedded::{Commerce, CreateCustomer};
93    ///
94    /// let commerce = Commerce::new("./store.db")?;
95    ///
96    /// let customer = commerce.customers().create(CreateCustomer {
97    ///     email: "alice@example.com".into(),
98    ///     first_name: "Alice".into(),
99    ///     last_name: "Smith".into(),
100    ///     ..Default::default()
101    /// })?;
102    /// # Ok::<(), stateset_embedded::CommerceError>(())
103    /// ```
104    #[must_use]
105    pub fn customers(&self) -> Customers {
106        #[cfg(feature = "events")]
107        {
108            Customers::new(self.db.clone(), self.event_system.clone(), self.metrics.clone())
109        }
110        #[cfg(not(feature = "events"))]
111        {
112            Customers::new(self.db.clone(), self.metrics.clone())
113        }
114    }
115
116    /// Access product operations.
117    ///
118    /// # Example
119    ///
120    /// ```rust,ignore
121    /// use stateset_embedded::{Commerce, CreateProduct, CreateProductVariant};
122    /// use rust_decimal_macros::dec;
123    ///
124    /// let commerce = Commerce::new("./store.db")?;
125    ///
126    /// let product = commerce.products().create(CreateProduct {
127    ///     name: "Premium Widget".into(),
128    ///     description: Some("A high-quality widget".into()),
129    ///     variants: Some(vec![CreateProductVariant {
130    ///         sku: "WIDGET-001".into(),
131    ///         price: dec!(49.99),
132    ///         ..Default::default()
133    ///     }]),
134    ///     ..Default::default()
135    /// })?;
136    /// # Ok::<(), stateset_embedded::CommerceError>(())
137    /// ```
138    #[must_use]
139    pub fn products(&self) -> Products {
140        #[cfg(feature = "events")]
141        {
142            Products::new(self.db.clone(), self.event_system.clone(), self.metrics.clone())
143        }
144        #[cfg(not(feature = "events"))]
145        {
146            Products::new(self.db.clone(), self.metrics.clone())
147        }
148    }
149
150    /// Access custom objects (custom states / metaobjects) operations.
151    #[must_use]
152    pub fn custom_objects(&self) -> CustomObjects {
153        #[cfg(feature = "events")]
154        {
155            CustomObjects::new(self.db.clone(), self.event_system.clone())
156        }
157        #[cfg(not(feature = "events"))]
158        {
159            CustomObjects::new(self.db.clone())
160        }
161    }
162
163    /// Alias for `custom_objects()` (for users who prefer the "custom states" name).
164    #[must_use]
165    pub fn custom_states(&self) -> CustomObjects {
166        self.custom_objects()
167    }
168
169    /// Access return operations.
170    ///
171    /// # Example
172    ///
173    /// ```rust,ignore
174    /// use stateset_embedded::{Commerce, CreateReturn, CreateReturnItem, ReturnReason};
175    /// use uuid::Uuid;
176    ///
177    /// let commerce = Commerce::new("./store.db")?;
178    ///
179    /// let ret = commerce.returns().create(CreateReturn {
180    ///     order_id: Uuid::new_v4(),
181    ///     reason: ReturnReason::Defective,
182    ///     items: vec![CreateReturnItem {
183    ///         order_item_id: Uuid::new_v4(),
184    ///         quantity: 1,
185    ///         ..Default::default()
186    ///     }],
187    ///     ..Default::default()
188    /// })?;
189    /// # Ok::<(), stateset_embedded::CommerceError>(())
190    /// ```
191    #[must_use]
192    pub fn returns(&self) -> Returns {
193        #[cfg(feature = "events")]
194        {
195            Returns::new(self.db.clone(), self.event_system.clone(), self.metrics.clone())
196        }
197        #[cfg(not(feature = "events"))]
198        {
199            Returns::new(self.db.clone(), self.metrics.clone())
200        }
201    }
202
203    /// Access Bill of Materials (BOM) operations.
204    ///
205    /// # Example
206    ///
207    /// ```rust,ignore
208    /// use stateset_embedded::{Commerce, CreateBom, CreateBomComponent};
209    /// use rust_decimal_macros::dec;
210    /// use uuid::Uuid;
211    ///
212    /// let commerce = Commerce::new("./store.db")?;
213    ///
214    /// let bom = commerce.bom().create(CreateBom {
215    ///     product_id: Uuid::new_v4(),
216    ///     name: "Widget Assembly".into(),
217    ///     components: Some(vec![
218    ///         CreateBomComponent {
219    ///             name: "Part A".into(),
220    ///             quantity: dec!(2),
221    ///             ..Default::default()
222    ///         },
223    ///     ]),
224    ///     ..Default::default()
225    /// })?;
226    /// # Ok::<(), stateset_embedded::CommerceError>(())
227    /// ```
228    #[must_use]
229    pub fn bom(&self) -> Bom {
230        Bom::new(self.db.clone())
231    }
232
233    /// Access work order operations.
234    ///
235    /// # Example
236    ///
237    /// ```rust,ignore
238    /// use stateset_embedded::{Commerce, CreateWorkOrder};
239    /// use rust_decimal_macros::dec;
240    /// use uuid::Uuid;
241    ///
242    /// let commerce = Commerce::new("./store.db")?;
243    ///
244    /// let wo = commerce.work_orders().create(CreateWorkOrder {
245    ///     product_id: Uuid::new_v4(),
246    ///     quantity_to_build: dec!(100),
247    ///     ..Default::default()
248    /// })?;
249    ///
250    /// // Start production
251    /// let wo = commerce.work_orders().start(wo.id)?;
252    /// # Ok::<(), stateset_embedded::CommerceError>(())
253    /// ```
254    #[must_use]
255    pub fn work_orders(&self) -> WorkOrders {
256        WorkOrders::new(self.db.clone())
257    }
258
259    /// Access shipment operations.
260    ///
261    /// # Example
262    ///
263    /// ```rust,ignore
264    /// use stateset_embedded::{Commerce, CreateShipment, CreateShipmentItem, ShippingCarrier};
265    /// use uuid::Uuid;
266    ///
267    /// let commerce = Commerce::new("./store.db")?;
268    ///
269    /// let shipment = commerce.shipments().create(CreateShipment {
270    ///     order_id: Uuid::new_v4(),
271    ///     carrier: Some(ShippingCarrier::Ups),
272    ///     recipient_name: "Alice Smith".into(),
273    ///     shipping_address: "123 Main St, City, ST 12345".into(),
274    ///     items: Some(vec![CreateShipmentItem {
275    ///         sku: "SKU-001".into(),
276    ///         name: "Widget".into(),
277    ///         quantity: 2,
278    ///         ..Default::default()
279    ///     }]),
280    ///     ..Default::default()
281    /// })?;
282    ///
283    /// // Ship with tracking number
284    /// let shipment = commerce.shipments().ship(shipment.id, Some("1Z999AA10123456784".into()))?;
285    ///
286    /// // Mark as delivered
287    /// let shipment = commerce.shipments().mark_delivered(shipment.id)?;
288    /// # Ok::<(), stateset_embedded::CommerceError>(())
289    /// ```
290    #[must_use]
291    pub fn shipments(&self) -> Shipments {
292        Shipments::new(self.db.clone(), self.metrics.clone())
293    }
294
295    /// Access payment operations.
296    ///
297    /// # Example
298    ///
299    /// ```rust,ignore
300    /// use stateset_embedded::{Commerce, CreatePayment, PaymentMethodType, CardBrand};
301    /// use rust_decimal_macros::dec;
302    /// use uuid::Uuid;
303    ///
304    /// let commerce = Commerce::new("./store.db")?;
305    ///
306    /// let payment = commerce.payments().create(CreatePayment {
307    ///     order_id: Some(Uuid::new_v4()),
308    ///     payment_method: PaymentMethodType::CreditCard,
309    ///     amount: dec!(99.99),
310    ///     card_brand: Some(CardBrand::Visa),
311    ///     card_last4: Some("4242".into()),
312    ///     ..Default::default()
313    /// })?;
314    ///
315    /// // Mark payment as completed
316    /// let payment = commerce.payments().mark_completed(payment.id)?;
317    /// # Ok::<(), stateset_embedded::CommerceError>(())
318    /// ```
319    #[must_use]
320    pub fn payments(&self) -> Payments {
321        Payments::new(self.db.clone(), self.metrics.clone())
322    }
323
324    /// Access warranty operations.
325    ///
326    /// # Example
327    ///
328    /// ```rust,ignore
329    /// use stateset_embedded::{Commerce, CreateWarranty, WarrantyType};
330    /// use uuid::Uuid;
331    ///
332    /// let commerce = Commerce::new("./store.db")?;
333    ///
334    /// let warranty = commerce.warranties().create(CreateWarranty {
335    ///     customer_id: Uuid::new_v4(),
336    ///     product_id: Some(Uuid::new_v4()),
337    ///     warranty_type: Some(WarrantyType::Extended),
338    ///     duration_months: Some(24),
339    ///     ..Default::default()
340    /// })?;
341    ///
342    /// // Check if warranty is valid
343    /// assert!(commerce.warranties().is_valid(warranty.id)?);
344    /// # Ok::<(), stateset_embedded::CommerceError>(())
345    /// ```
346    #[must_use]
347    pub fn warranties(&self) -> Warranties {
348        Warranties::new(self.db.clone())
349    }
350
351    /// Access purchase order operations.
352    ///
353    /// # Example
354    ///
355    /// ```rust,ignore
356    /// use stateset_embedded::{Commerce, CreatePurchaseOrder, CreatePurchaseOrderItem, CreateSupplier};
357    /// use rust_decimal_macros::dec;
358    ///
359    /// let commerce = Commerce::new("./store.db")?;
360    ///
361    /// // Create a supplier
362    /// let supplier = commerce.purchase_orders().create_supplier(CreateSupplier {
363    ///     name: "Acme Supplies".into(),
364    ///     email: Some("orders@acme.com".into()),
365    ///     ..Default::default()
366    /// })?;
367    ///
368    /// // Create a purchase order
369    /// let po = commerce.purchase_orders().create(CreatePurchaseOrder {
370    ///     supplier_id: supplier.id,
371    ///     items: vec![CreatePurchaseOrderItem {
372    ///         sku: "PART-001".into(),
373    ///         name: "Widget Part".into(),
374    ///         quantity: dec!(100),
375    ///         unit_cost: dec!(5.99),
376    ///         ..Default::default()
377    ///     }],
378    ///     ..Default::default()
379    /// })?;
380    ///
381    /// // Approve and send
382    /// let po = commerce.purchase_orders().submit(po.id)?;
383    /// let po = commerce.purchase_orders().approve(po.id, "admin")?;
384    /// let po = commerce.purchase_orders().send(po.id)?;
385    /// # Ok::<(), stateset_embedded::CommerceError>(())
386    /// ```
387    #[must_use]
388    pub fn purchase_orders(&self) -> PurchaseOrders {
389        PurchaseOrders::new(self.db.clone())
390    }
391
392    /// Access invoice operations.
393    ///
394    /// # Example
395    ///
396    /// ```rust,ignore
397    /// use stateset_embedded::{Commerce, CreateInvoice, CreateInvoiceItem, RecordInvoicePayment};
398    /// use rust_decimal_macros::dec;
399    /// use uuid::Uuid;
400    ///
401    /// let commerce = Commerce::new("./store.db")?;
402    ///
403    /// let invoice = commerce.invoices().create(CreateInvoice {
404    ///     customer_id: Uuid::new_v4(),
405    ///     billing_email: Some("customer@example.com".into()),
406    ///     items: vec![CreateInvoiceItem {
407    ///         description: "Professional Services".into(),
408    ///         quantity: dec!(10),
409    ///         unit_price: dec!(150.00),
410    ///         ..Default::default()
411    ///     }],
412    ///     ..Default::default()
413    /// })?;
414    ///
415    /// // Send and record payment
416    /// let invoice = commerce.invoices().send(invoice.id)?;
417    /// let invoice = commerce.invoices().record_payment(invoice.id, RecordInvoicePayment {
418    ///     amount: dec!(1500.00),
419    ///     payment_method: Some("credit_card".into()),
420    ///     ..Default::default()
421    /// })?;
422    /// # Ok::<(), stateset_embedded::CommerceError>(())
423    /// ```
424    #[must_use]
425    pub fn invoices(&self) -> Invoices {
426        Invoices::new(self.db.clone())
427    }
428
429    /// Access cart and checkout operations.
430    ///
431    /// # Example
432    ///
433    /// ```rust,ignore
434    /// use stateset_embedded::{Commerce, CreateCart, AddCartItem, CartAddress};
435    /// use rust_decimal_macros::dec;
436    /// use uuid::Uuid;
437    ///
438    /// let commerce = Commerce::new("./store.db")?;
439    ///
440    /// // Create a cart
441    /// let cart = commerce.carts().create(CreateCart {
442    ///     customer_email: Some("alice@example.com".into()),
443    ///     customer_name: Some("Alice Smith".into()),
444    ///     ..Default::default()
445    /// })?;
446    ///
447    /// // Add items
448    /// commerce.carts().add_item(cart.id, AddCartItem {
449    ///     sku: "SKU-001".into(),
450    ///     name: "Widget".into(),
451    ///     quantity: 2,
452    ///     unit_price: dec!(29.99),
453    ///     ..Default::default()
454    /// })?;
455    ///
456    /// // Set shipping address
457    /// commerce.carts().set_shipping_address(cart.id, CartAddress {
458    ///     first_name: "Alice".into(),
459    ///     last_name: "Smith".into(),
460    ///     line1: "123 Main St".into(),
461    ///     city: "Anytown".into(),
462    ///     postal_code: "12345".into(),
463    ///     country: "US".into(),
464    ///     ..Default::default()
465    /// })?;
466    ///
467    /// // Complete checkout
468    /// let result = commerce.carts().complete(cart.id)?;
469    /// println!("Order created: {}", result.order_number);
470    /// # Ok::<(), stateset_embedded::CommerceError>(())
471    /// ```
472    #[must_use]
473    pub fn carts(&self) -> Carts {
474        Carts::new(self.db.clone(), self.metrics.clone())
475    }
476
477    /// Access analytics and forecasting operations.
478    ///
479    /// # Example
480    ///
481    /// ```rust,ignore
482    /// use stateset_embedded::{Commerce, AnalyticsQuery, TimePeriod};
483    ///
484    /// let commerce = Commerce::new("./store.db")?;
485    ///
486    /// // Get sales summary
487    /// let summary = commerce.analytics().sales_summary(
488    ///     AnalyticsQuery::new().period(TimePeriod::Last30Days)
489    /// )?;
490    /// println!("Revenue: ${}", summary.total_revenue);
491    /// println!("Orders: {}", summary.order_count);
492    ///
493    /// // Get top products
494    /// let top = commerce.analytics().top_products(
495    ///     AnalyticsQuery::new().period(TimePeriod::ThisMonth).limit(10)
496    /// )?;
497    ///
498    /// // Get inventory forecast
499    /// let forecasts = commerce.analytics().demand_forecast(None, 30)?;
500    /// for f in forecasts {
501    ///     if let Some(days) = f.days_until_stockout {
502    ///         if days < 14 {
503    ///             println!("WARNING: {} will stock out in {} days", f.sku, days);
504    ///         }
505    ///     }
506    /// }
507    /// # Ok::<(), stateset_embedded::CommerceError>(())
508    /// ```
509    #[must_use]
510    pub fn analytics(&self) -> Analytics {
511        Analytics::new(self.db.clone())
512    }
513
514    /// Access currency and exchange rate operations.
515    ///
516    /// # Example
517    ///
518    /// ```rust,ignore
519    /// use stateset_embedded::{Commerce, Currency, ConvertCurrency};
520    /// use rust_decimal_macros::dec;
521    ///
522    /// let commerce = Commerce::new("./store.db")?;
523    ///
524    /// // Get exchange rate
525    /// if let Some(rate) = commerce.currency().get_rate(Currency::USD, Currency::EUR)? {
526    ///     println!("1 USD = {} EUR", rate.rate);
527    /// }
528    ///
529    /// // Convert currency
530    /// let result = commerce.currency().convert(ConvertCurrency {
531    ///     from: Currency::USD,
532    ///     to: Currency::EUR,
533    ///     amount: dec!(100.00),
534    /// })?;
535    /// println!("$100 USD = €{} EUR", result.converted_amount);
536    ///
537    /// // Set exchange rates
538    /// commerce.currency().set_rate(stateset_embedded::SetExchangeRate {
539    ///     base_currency: Currency::USD,
540    ///     quote_currency: Currency::EUR,
541    ///     rate: dec!(0.92),
542    ///     source: Some("manual".into()),
543    /// })?;
544    ///
545    /// // Update store settings
546    /// let settings = commerce.currency().get_settings()?;
547    /// println!("Base currency: {}", settings.base_currency);
548    /// # Ok::<(), stateset_embedded::CommerceError>(())
549    /// ```
550    #[must_use]
551    pub fn currency(&self) -> CurrencyOps {
552        CurrencyOps::new(self.db.clone())
553    }
554
555    /// Access tax calculation and management operations.
556    ///
557    /// Provides multi-jurisdiction tax calculation with support for:
558    /// - US sales tax (state, county, city levels)
559    /// - EU VAT (standard, reduced, zero-rated)
560    /// - Canadian GST/HST/PST/QST
561    /// - Customer exemptions (resale, non-profit, etc.)
562    ///
563    /// # Example
564    ///
565    /// ```rust,ignore
566    /// use stateset_embedded::{Commerce, TaxCalculationRequest, TaxLineItem, TaxAddress, ProductTaxCategory};
567    /// use rust_decimal_macros::dec;
568    ///
569    /// let commerce = Commerce::new("./store.db")?;
570    ///
571    /// // Calculate tax for a transaction
572    /// let result = commerce.tax().calculate(TaxCalculationRequest {
573    ///     line_items: vec![TaxLineItem {
574    ///         id: "item-1".into(),
575    ///         quantity: dec!(2),
576    ///         unit_price: dec!(29.99),
577    ///         tax_category: ProductTaxCategory::Standard,
578    ///         ..Default::default()
579    ///     }],
580    ///     shipping_address: TaxAddress {
581    ///         country: "US".into(),
582    ///         state: Some("CA".into()),
583    ///         ..Default::default()
584    ///     },
585    ///     ..Default::default()
586    /// })?;
587    ///
588    /// println!("Tax: ${}", result.total_tax);
589    /// println!("Total: ${}", result.total);
590    ///
591    /// // Check effective rate for an address
592    /// let rate = commerce.tax().get_effective_rate(
593    ///     &TaxAddress { country: "US".into(), state: Some("TX".into()), ..Default::default() },
594    ///     ProductTaxCategory::Standard,
595    /// )?;
596    /// println!("Texas tax rate: {}%", rate * dec!(100));
597    /// # Ok::<(), stateset_embedded::CommerceError>(())
598    /// ```
599    #[must_use]
600    pub fn tax(&self) -> Tax {
601        Tax::new(self.db.clone())
602    }
603
604    /// Access promotions and discount operations.
605    ///
606    /// Provides comprehensive promotions engine supporting:
607    /// - Percentage and fixed amount discounts
608    /// - Buy X Get Y (BOGO) promotions
609    /// - Free shipping offers
610    /// - Tiered discounts based on spend/quantity
611    /// - Coupon code management
612    /// - Automatic promotions
613    ///
614    /// # Example
615    ///
616    /// ```rust,ignore
617    /// use stateset_embedded::{Commerce, CreatePromotion, PromotionType, ApplyPromotionsRequest, PromotionLineItem};
618    /// use rust_decimal_macros::dec;
619    ///
620    /// let commerce = Commerce::new("./store.db")?;
621    ///
622    /// // Create a 20% off promotion
623    /// let promo = commerce.promotions().create(CreatePromotion {
624    ///     name: "Summer Sale".into(),
625    ///     promotion_type: PromotionType::PercentageOff,
626    ///     percentage_off: Some(dec!(0.20)),
627    ///     ..Default::default()
628    /// })?;
629    ///
630    /// // Activate it
631    /// commerce.promotions().activate(promo.id)?;
632    ///
633    /// // Create a coupon code
634    /// commerce.promotions().create_coupon(stateset_embedded::CreateCouponCode {
635    ///     promotion_id: promo.id,
636    ///     code: "SUMMER20".into(),
637    ///     usage_limit: Some(100),
638    ///     ..Default::default()
639    /// })?;
640    ///
641    /// // Apply promotions to a cart
642    /// let result = commerce.promotions().apply(ApplyPromotionsRequest {
643    ///     subtotal: dec!(100.00),
644    ///     coupon_codes: vec!["SUMMER20".into()],
645    ///     line_items: vec![PromotionLineItem {
646    ///         id: "item-1".into(),
647    ///         quantity: 2,
648    ///         unit_price: dec!(50.00),
649    ///         line_total: dec!(100.00),
650    ///         ..Default::default()
651    ///     }],
652    ///     ..Default::default()
653    /// })?;
654    ///
655    /// println!("Discount: ${}", result.total_discount);
656    /// println!("Final total: ${}", result.grand_total);
657    /// # Ok::<(), stateset_embedded::CommerceError>(())
658    /// ```
659    #[must_use]
660    pub fn promotions(&self) -> Promotions {
661        Promotions::new(self.db.clone())
662    }
663
664    /// Access subscription management operations.
665    ///
666    /// # Example
667    ///
668    /// ```rust,ignore
669    /// use stateset_embedded::{Commerce, CreateSubscriptionPlan, CreateSubscription, BillingInterval};
670    /// use rust_decimal_macros::dec;
671    /// use uuid::Uuid;
672    ///
673    /// let commerce = Commerce::new("./store.db")?;
674    ///
675    /// // Create a subscription plan
676    /// let plan = commerce.subscriptions().create_plan(CreateSubscriptionPlan {
677    ///     name: "Monthly Coffee Box".into(),
678    ///     billing_interval: BillingInterval::Monthly,
679    ///     price: dec!(29.99),
680    ///     trial_days: Some(14),
681    ///     ..Default::default()
682    /// })?;
683    ///
684    /// // Activate the plan
685    /// commerce.subscriptions().activate_plan(plan.id)?;
686    ///
687    /// // Subscribe a customer
688    /// let subscription = commerce.subscriptions().subscribe(CreateSubscription {
689    ///     customer_id: Uuid::new_v4(),
690    ///     plan_id: plan.id,
691    ///     ..Default::default()
692    /// })?;
693    ///
694    /// println!("Subscription #{} created", subscription.subscription_number);
695    /// # Ok::<(), stateset_embedded::CommerceError>(())
696    /// ```
697    #[must_use]
698    pub fn subscriptions(&self) -> Subscriptions {
699        Subscriptions::new(self.db.clone(), self.metrics.clone())
700    }
701
702    /// Access quality control operations.
703    ///
704    /// # Example
705    ///
706    /// ```rust,ignore
707    /// use stateset_embedded::{Commerce, CreateInspection, InspectionType};
708    /// use uuid::Uuid;
709    ///
710    /// let commerce = Commerce::new("./store.db")?;
711    ///
712    /// let inspection = commerce.quality().create_inspection(CreateInspection {
713    ///     inspection_type: InspectionType::Receiving,
714    ///     reference_type: "purchase_order".into(),
715    ///     reference_id: Uuid::new_v4(),
716    ///     ..Default::default()
717    /// })?;
718    ///
719    /// println!("Created inspection #{}", inspection.inspection_number);
720    /// # Ok::<(), stateset_embedded::CommerceError>(())
721    /// ```
722    #[must_use]
723    pub fn quality(&self) -> Quality {
724        Quality::new(self.db.clone())
725    }
726
727    /// Access lot/batch tracking operations.
728    ///
729    /// # Example
730    ///
731    /// ```rust,ignore
732    /// use stateset_embedded::{Commerce, CreateLot};
733    /// use chrono::{Utc, Duration};
734    /// use rust_decimal_macros::dec;
735    ///
736    /// let commerce = Commerce::new("./store.db")?;
737    ///
738    /// let lot = commerce.lots().create(CreateLot {
739    ///     lot_number: Some("LOT-2025-001".into()),
740    ///     sku: "RAW-001".into(),
741    ///     quantity_produced: dec!(1000),
742    ///     expiration_date: Some(Utc::now() + Duration::days(365)),
743    ///     ..Default::default()
744    /// })?;
745    ///
746    /// println!("Created lot {}", lot.lot_number);
747    /// # Ok::<(), stateset_embedded::CommerceError>(())
748    /// ```
749    #[must_use]
750    pub fn lots(&self) -> Lots {
751        Lots::new(self.db.clone())
752    }
753
754    /// Access serial number management operations.
755    ///
756    /// # Example
757    ///
758    /// ```rust,ignore
759    /// use stateset_embedded::{Commerce, CreateSerialNumber};
760    ///
761    /// let commerce = Commerce::new("./store.db")?;
762    ///
763    /// let serial = commerce.serials().create(CreateSerialNumber {
764    ///     serial: Some("SN-12345-ABCD".into()),
765    ///     sku: "LAPTOP-PRO-15".into(),
766    ///     ..Default::default()
767    /// })?;
768    ///
769    /// println!("Created serial {}", serial.serial);
770    /// # Ok::<(), stateset_embedded::CommerceError>(())
771    /// ```
772    #[must_use]
773    pub fn serials(&self) -> Serials {
774        Serials::new(self.db.clone())
775    }
776
777    /// Access warehouse and location management operations.
778    ///
779    /// # Example
780    ///
781    /// ```rust,ignore
782    /// use stateset_embedded::{Commerce, CreateWarehouse, CreateLocation, WarehouseType, LocationType};
783    ///
784    /// let commerce = Commerce::new("./store.db")?;
785    ///
786    /// // Create a warehouse
787    /// let warehouse = commerce.warehouse().create_warehouse(CreateWarehouse {
788    ///     code: "WH-001".into(),
789    ///     name: "Main Distribution Center".into(),
790    ///     warehouse_type: WarehouseType::Distribution,
791    ///     ..Default::default()
792    /// })?;
793    ///
794    /// // Create a location
795    /// let location = commerce.warehouse().create_location(CreateLocation {
796    ///     warehouse_id: warehouse.id,
797    ///     location_type: LocationType::Pick,
798    ///     zone: Some("A".into()),
799    ///     aisle: Some("01".into()),
800    ///     ..Default::default()
801    /// })?;
802    ///
803    /// println!("Created location {} in {}", location.code, warehouse.name);
804    /// # Ok::<(), stateset_embedded::CommerceError>(())
805    /// ```
806    #[must_use]
807    pub fn warehouse(&self) -> WarehouseOps {
808        #[cfg(feature = "events")]
809        {
810            WarehouseOps::new(self.db.clone(), self.event_system.clone())
811        }
812        #[cfg(not(feature = "events"))]
813        {
814            WarehouseOps::new(self.db.clone())
815        }
816    }
817
818    /// Access receiving and goods receipt operations.
819    ///
820    /// # Example
821    ///
822    /// ```rust,ignore
823    /// use stateset_embedded::{Commerce, CreateReceipt, CreateReceiptItem, ReceiptType};
824    /// use rust_decimal_macros::dec;
825    ///
826    /// let commerce = Commerce::new("./store.db")?;
827    ///
828    /// // Create a receipt
829    /// let receipt = commerce.receiving().create_receipt(CreateReceipt {
830    ///     receipt_type: ReceiptType::PurchaseOrder,
831    ///     warehouse_id: 1,
832    ///     items: vec![CreateReceiptItem {
833    ///         sku: "WIDGET-001".into(),
834    ///         expected_quantity: dec!(100),
835    ///         ..Default::default()
836    ///     }],
837    ///     ..Default::default()
838    /// })?;
839    ///
840    /// println!("Created receipt {}", receipt.receipt_number);
841    /// # Ok::<(), stateset_embedded::CommerceError>(())
842    /// ```
843    #[must_use]
844    pub fn receiving(&self) -> Receiving {
845        Receiving::new(self.db.clone())
846    }
847
848    /// Access fulfillment (pick/pack/ship) operations.
849    ///
850    /// # Example
851    ///
852    /// ```rust,ignore
853    /// use stateset_embedded::{Commerce, CreateWave, PickTaskFilter};
854    /// use uuid::Uuid;
855    ///
856    /// let commerce = Commerce::new("./store.db")?;
857    ///
858    /// // Create a wave from orders
859    /// let wave = commerce.fulfillment().create_wave(CreateWave {
860    ///     warehouse_id: 1,
861    ///     order_ids: vec![Uuid::new_v4()],
862    ///     ..Default::default()
863    /// })?;
864    ///
865    /// // Get picks for the wave
866    /// let picks = commerce.fulfillment().get_picks_for_wave(wave.id)?;
867    /// # Ok::<(), stateset_embedded::CommerceError>(())
868    /// ```
869    #[must_use]
870    pub fn fulfillment(&self) -> Fulfillment {
871        Fulfillment::new(self.db.clone())
872    }
873
874    /// Access accounts payable (bills and supplier payments) operations.
875    ///
876    /// # Example
877    ///
878    /// ```rust,ignore
879    /// use stateset_embedded::{Commerce, CreateBill, CreateBillItem};
880    /// use rust_decimal_macros::dec;
881    /// use chrono::{Utc, Duration};
882    /// use uuid::Uuid;
883    ///
884    /// let commerce = Commerce::new("./store.db")?;
885    ///
886    /// // Create a bill from a supplier
887    /// let bill = commerce.accounts_payable().create_bill(CreateBill {
888    ///     supplier_id: Uuid::new_v4(),
889    ///     due_date: Utc::now() + Duration::days(30),
890    ///     items: vec![CreateBillItem {
891    ///         description: "Office supplies".into(),
892    ///         quantity: dec!(1),
893    ///         unit_price: dec!(150.00),
894    ///         ..Default::default()
895    ///     }],
896    ///     ..Default::default()
897    /// })?;
898    ///
899    /// // Get aging summary
900    /// let aging = commerce.accounts_payable().get_aging_summary()?;
901    /// println!("Total AP: ${}", aging.total);
902    /// # Ok::<(), stateset_embedded::CommerceError>(())
903    /// ```
904    #[must_use]
905    pub fn accounts_payable(&self) -> AccountsPayable {
906        #[cfg(feature = "events")]
907        {
908            AccountsPayable::new(self.db.clone(), self.event_system.clone())
909        }
910        #[cfg(not(feature = "events"))]
911        {
912            AccountsPayable::new(self.db.clone())
913        }
914    }
915
916    /// Access cost accounting operations.
917    ///
918    /// # Example
919    ///
920    /// ```rust,ignore
921    /// use stateset_embedded::{Commerce, SetItemCost, CostMethod};
922    /// use rust_decimal_macros::dec;
923    ///
924    /// let commerce = Commerce::new("./store.db")?;
925    ///
926    /// // Set standard cost for an item
927    /// let cost = commerce.cost_accounting().set_item_cost(SetItemCost {
928    ///     sku: "WIDGET-001".into(),
929    ///     cost_method: Some(CostMethod::Average),
930    ///     standard_cost: Some(dec!(10.00)),
931    ///     ..Default::default()
932    /// })?;
933    ///
934    /// // Get inventory valuation
935    /// let valuation = commerce.cost_accounting().get_inventory_valuation(CostMethod::Average)?;
936    /// println!("Total inventory value: ${}", valuation.total_value);
937    /// # Ok::<(), stateset_embedded::CommerceError>(())
938    /// ```
939    #[must_use]
940    pub fn cost_accounting(&self) -> CostAccounting {
941        CostAccounting::new(self.db.clone())
942    }
943
944    /// Access credit management operations.
945    ///
946    /// # Example
947    ///
948    /// ```rust,ignore
949    /// use stateset_embedded::{Commerce, CreateCreditAccount};
950    /// use rust_decimal_macros::dec;
951    /// use uuid::Uuid;
952    ///
953    /// let commerce = Commerce::new("./store.db")?;
954    ///
955    /// // Create credit account for a customer
956    /// let account = commerce.credit().create_credit_account(CreateCreditAccount {
957    ///     customer_id: Uuid::new_v4(),
958    ///     credit_limit: dec!(10000.00),
959    ///     payment_terms: Some("Net 30".into()),
960    ///     ..Default::default()
961    /// })?;
962    ///
963    /// // Check credit for an order
964    /// let result = commerce.credit().check_credit(account.customer_id, dec!(5000.00))?;
965    /// println!("Credit approved: {}", result.approved);
966    /// # Ok::<(), stateset_embedded::CommerceError>(())
967    /// ```
968    #[must_use]
969    pub fn credit(&self) -> Credit {
970        Credit::new(self.db.clone())
971    }
972
973    /// Access backorder management operations.
974    ///
975    /// # Example
976    ///
977    /// ```rust,ignore
978    /// use stateset_embedded::{Commerce, CreateBackorder, BackorderPriority};
979    /// use rust_decimal_macros::dec;
980    /// use uuid::Uuid;
981    ///
982    /// let commerce = Commerce::new("./store.db")?;
983    ///
984    /// // Create a backorder when inventory is unavailable
985    /// let backorder = commerce.backorder().create_backorder(CreateBackorder {
986    ///     order_id: Uuid::new_v4(),
987    ///     customer_id: Uuid::new_v4(),
988    ///     sku: "WIDGET-001".into(),
989    ///     quantity: dec!(50),
990    ///     priority: Some(BackorderPriority::High),
991    ///     ..Default::default()
992    /// })?;
993    ///
994    /// // Get overdue backorders
995    /// let overdue = commerce.backorder().get_overdue_backorders()?;
996    /// println!("Overdue backorders: {}", overdue.len());
997    /// # Ok::<(), stateset_embedded::CommerceError>(())
998    /// ```
999    #[must_use]
1000    pub fn backorder(&self) -> Backorders {
1001        Backorders::new(self.db.clone())
1002    }
1003
1004    /// Access accounts receivable operations.
1005    ///
1006    /// Provides AR aging, collection activities, write-offs, credit memos,
1007    /// and customer statement generation.
1008    ///
1009    /// # Example
1010    ///
1011    /// ```rust,ignore
1012    /// use stateset_embedded::Commerce;
1013    ///
1014    /// let commerce = Commerce::new("./store.db")?;
1015    ///
1016    /// // Get AR aging summary
1017    /// let aging = commerce.accounts_receivable().get_aging_summary()?;
1018    /// println!("Current: ${}", aging.current);
1019    /// println!("1-30 days: ${}", aging.days_1_30);
1020    /// println!("31-60 days: ${}", aging.days_31_60);
1021    /// println!("61-90 days: ${}", aging.days_61_90);
1022    /// println!("90+ days: ${}", aging.days_over_90);
1023    ///
1024    /// // Get DSO (Days Sales Outstanding)
1025    /// let dso = commerce.accounts_receivable().get_dso(30)?;
1026    /// println!("DSO (30 day): {}", dso);
1027    /// # Ok::<(), stateset_embedded::CommerceError>(())
1028    /// ```
1029    #[must_use]
1030    pub fn accounts_receivable(&self) -> AccountsReceivable {
1031        AccountsReceivable::new(self.db.clone())
1032    }
1033
1034    /// Access general ledger operations.
1035    ///
1036    /// Provides chart of accounts management, journal entries,
1037    /// period management, and financial reporting.
1038    ///
1039    /// # Example
1040    ///
1041    /// ```rust,ignore
1042    /// use stateset_embedded::{Commerce, CreateJournalEntry};
1043    /// use chrono::NaiveDate;
1044    ///
1045    /// let commerce = Commerce::new("./store.db")?;
1046    ///
1047    /// // Initialize standard chart of accounts
1048    /// commerce.general_ledger().initialize_chart_of_accounts()?;
1049    ///
1050    /// // Generate trial balance
1051    /// let trial_balance = commerce.general_ledger().get_trial_balance(
1052    ///     NaiveDate::from_ymd_opt(2025, 1, 31).unwrap()
1053    /// )?;
1054    /// println!("Total Debits: ${}", trial_balance.total_debits);
1055    /// println!("Total Credits: ${}", trial_balance.total_credits);
1056    /// println!("Balanced: {}", trial_balance.is_balanced);
1057    ///
1058    /// // Generate income statement
1059    /// let income = commerce.general_ledger().get_income_statement(
1060    ///     NaiveDate::from_ymd_opt(2025, 1, 1).unwrap(),
1061    ///     NaiveDate::from_ymd_opt(2025, 1, 31).unwrap(),
1062    /// )?;
1063    /// println!("Revenue: ${}", income.total_revenue);
1064    /// println!("Expenses: ${}", income.total_expenses);
1065    /// println!("Net Income: ${}", income.net_income);
1066    /// # Ok::<(), stateset_embedded::CommerceError>(())
1067    /// ```
1068    #[must_use]
1069    pub fn general_ledger(&self) -> GeneralLedger {
1070        #[cfg(feature = "events")]
1071        {
1072            GeneralLedger::new(self.db.clone(), self.event_system.clone())
1073        }
1074        #[cfg(not(feature = "events"))]
1075        {
1076            GeneralLedger::new(self.db.clone())
1077        }
1078    }
1079
1080    /// Access x402 payment protocol and agent card operations.
1081    ///
1082    /// Provides x402 stablecoin payment intents for AI agent commerce,
1083    /// including intent creation, signing, settlement tracking, and
1084    /// agent card management for A2A (agent-to-agent) commerce.
1085    ///
1086    /// # Example
1087    ///
1088    /// ```rust,ignore
1089    /// use stateset_embedded::{Commerce, CreateX402PaymentIntent, X402Network, X402Asset};
1090    /// use rust_decimal_macros::dec;
1091    ///
1092    /// let commerce = Commerce::new("./store.db")?;
1093    ///
1094    /// // Create a payment intent
1095    /// let intent = commerce.x402().create_intent(CreateX402PaymentIntent {
1096    ///     payer_address: "0xBuyer...".into(),
1097    ///     payee_address: "0xSeller...".into(),
1098    ///     amount: dec!(100.00),
1099    ///     asset: X402Asset::Usdc,
1100    ///     network: X402Network::SetChain,
1101    ///     ..Default::default()
1102    /// })?;
1103    ///
1104    /// // Register an agent card
1105    /// use stateset_embedded::{CreateAgentCard, A2ASkill};
1106    ///
1107    /// let card = commerce.x402().register_agent(CreateAgentCard {
1108    ///     name: "Commerce Bot".into(),
1109    ///     wallet_address: "0xAgent...".into(),
1110    ///     public_key: "ed25519_pubkey_base64".into(),
1111    ///     supported_networks: vec![X402Network::SetChain],
1112    ///     supported_assets: vec![X402Asset::Usdc, X402Asset::SsUsd],
1113    ///     a2a_skills: Some(vec![A2ASkill::Sell, A2ASkill::Quote]),
1114    ///     ..Default::default()
1115    /// })?;
1116    ///
1117    /// // Discover agents with specific capabilities
1118    /// let sellers = commerce.x402().discover_agents(
1119    ///     Some(vec![X402Network::SetChain]),
1120    ///     Some(vec![X402Asset::Usdc]),
1121    ///     Some(vec!["Sell".to_string()]),
1122    ///     None,
1123    /// )?;
1124    /// # Ok::<(), stateset_embedded::CommerceError>(())
1125    /// ```
1126    #[must_use]
1127    pub fn x402(&self) -> X402 {
1128        X402::new(self.db.clone())
1129    }
1130
1131    /// Access ERC-8004 trustless agent registries.
1132    ///
1133    /// Provides identity, reputation, and validation registry operations
1134    /// for trustless agent discovery across organizational boundaries.
1135    #[must_use]
1136    pub fn erc8004(&self) -> Erc8004 {
1137        Erc8004::new(self.db.clone())
1138    }
1139
1140    /// Access gift card operations.
1141    ///
1142    /// Provides gift card issuance, charging, refunding, and transaction history.
1143    #[must_use]
1144    pub fn gift_cards(&self) -> GiftCards {
1145        GiftCards::new(self.db.clone())
1146    }
1147
1148    /// Access store credit operations.
1149    ///
1150    /// Provides store credit management including balance adjustments and application to orders.
1151    #[must_use]
1152    pub fn store_credits(&self) -> StoreCredits {
1153        StoreCredits::new(self.db.clone())
1154    }
1155
1156    /// Access customer segment operations.
1157    ///
1158    /// Provides customer grouping, membership management, and segment targeting.
1159    #[must_use]
1160    pub fn segments(&self) -> Segments {
1161        Segments::new(self.db.clone())
1162    }
1163
1164    /// Access shipping zone and method operations.
1165    ///
1166    /// Provides shipping zone management, method configuration, and rate calculation.
1167    #[must_use]
1168    pub fn shipping_zones(&self) -> ShippingZones {
1169        ShippingZones::new(self.db.clone())
1170    }
1171
1172    /// Access sales / fulfillment channel operations.
1173    #[must_use]
1174    pub fn channels(&self) -> crate::Channels {
1175        crate::Channels::new(self.db.clone())
1176    }
1177
1178    /// Access B2B company (account) operations.
1179    #[must_use]
1180    pub fn companies(&self) -> crate::Companies {
1181        crate::Companies::new(self.db.clone())
1182    }
1183
1184    /// Access transfer order operations (inter-warehouse stock movement).
1185    #[must_use]
1186    pub fn transfer_orders(&self) -> crate::TransferOrders {
1187        crate::TransferOrders::new(self.db.clone())
1188    }
1189
1190    /// Access units-of-measure operations (classes, UOMs, conversion rules).
1191    #[must_use]
1192    pub fn units_of_measure(&self) -> crate::UnitsOfMeasure {
1193        crate::UnitsOfMeasure::new(self.db.clone())
1194    }
1195
1196    /// Access production batch operations.
1197    #[must_use]
1198    pub fn production_batches(&self) -> crate::ProductionBatches {
1199        crate::ProductionBatches::new(self.db.clone())
1200    }
1201
1202    /// Access supplier SKU operations.
1203    #[must_use]
1204    pub fn supplier_skus(&self) -> crate::SupplierSkus {
1205        crate::SupplierSkus::new(self.db.clone())
1206    }
1207
1208    /// Access fixed asset register operations.
1209    #[must_use]
1210    pub fn fixed_assets(&self) -> crate::FixedAssets {
1211        #[cfg(feature = "events")]
1212        {
1213            crate::FixedAssets::new(self.db.clone(), self.event_system.clone())
1214        }
1215        #[cfg(not(feature = "events"))]
1216        {
1217            crate::FixedAssets::new(self.db.clone())
1218        }
1219    }
1220
1221    /// Access backup, restore and export/import operations.
1222    ///
1223    /// # Example
1224    ///
1225    /// ```rust,ignore
1226    /// let commerce = stateset_embedded::Commerce::new("./store.db")?;
1227    /// let report = commerce.maintenance().backup_to("./backups/nightly.db")?;
1228    /// # Ok::<(), stateset_embedded::CommerceError>(())
1229    /// ```
1230    #[must_use]
1231    pub fn maintenance(&self) -> crate::Maintenance {
1232        #[cfg(feature = "sqlite")]
1233        {
1234            crate::Maintenance::new(
1235                self.db.clone(),
1236                self.sqlite_db.clone(),
1237                self.sqlite_path.clone(),
1238            )
1239        }
1240        #[cfg(not(feature = "sqlite"))]
1241        {
1242            crate::Maintenance::new(self.db.clone())
1243        }
1244    }
1245
1246    /// Access revenue recognition (ASC 606) operations.
1247    #[must_use]
1248    pub fn revenue_recognition(&self) -> crate::RevenueRecognition {
1249        #[cfg(feature = "events")]
1250        {
1251            crate::RevenueRecognition::new(self.db.clone(), self.event_system.clone())
1252        }
1253        #[cfg(not(feature = "events"))]
1254        {
1255            crate::RevenueRecognition::new(self.db.clone())
1256        }
1257    }
1258
1259    /// Access vendor return operations.
1260    #[must_use]
1261    pub fn vendor_returns(&self) -> crate::VendorReturns {
1262        crate::VendorReturns::new(self.db.clone())
1263    }
1264
1265    /// Access vendor credit operations.
1266    #[must_use]
1267    pub fn vendor_credits(&self) -> crate::VendorCredits {
1268        crate::VendorCredits::new(self.db.clone())
1269    }
1270
1271    /// Access payment obligation operations.
1272    #[must_use]
1273    pub fn payment_obligations(&self) -> crate::PaymentObligations {
1274        crate::PaymentObligations::new(self.db.clone())
1275    }
1276
1277    /// Access price level (B2B pricing tier) operations.
1278    #[must_use]
1279    pub fn price_levels(&self) -> crate::PriceLevels {
1280        crate::PriceLevels::new(self.db.clone())
1281    }
1282
1283    /// Access prepayment operations.
1284    #[must_use]
1285    pub fn prepayments(&self) -> crate::Prepayments {
1286        crate::Prepayments::new(self.db.clone())
1287    }
1288
1289    /// Access price schedule (time-bounded pricing) operations.
1290    #[must_use]
1291    pub fn price_schedules(&self) -> crate::PriceSchedules {
1292        crate::PriceSchedules::new(self.db.clone())
1293    }
1294
1295    /// Access activity log (subject history) operations.
1296    #[must_use]
1297    pub fn activity_logs(&self) -> crate::ActivityLogs {
1298        crate::ActivityLogs::new(self.db.clone())
1299    }
1300
1301    /// Access integration mapping operations.
1302    #[must_use]
1303    pub fn integration_mappings(&self) -> crate::IntegrationMappings {
1304        crate::IntegrationMappings::new(self.db.clone())
1305    }
1306
1307    /// Access inbound shipment (ASN) operations.
1308    #[must_use]
1309    pub fn inbound_shipments(&self) -> crate::InboundShipments {
1310        crate::InboundShipments::new(self.db.clone())
1311    }
1312
1313    /// Access purgatory (order ingestion staging) operations.
1314    #[must_use]
1315    pub fn purgatory(&self) -> crate::Purgatory {
1316        crate::Purgatory::new(self.db.clone())
1317    }
1318
1319    /// Access print station operations.
1320    #[must_use]
1321    pub fn print_stations(&self) -> crate::PrintStations {
1322        crate::PrintStations::new(self.db.clone())
1323    }
1324
1325    /// Access EDI document operations.
1326    #[must_use]
1327    pub fn edi_documents(&self) -> crate::EdiDocuments {
1328        crate::EdiDocuments::new(self.db.clone())
1329    }
1330
1331    /// Access integration field-mapping operations.
1332    #[must_use]
1333    pub fn integration_field_mappings(&self) -> crate::IntegrationFieldMappings {
1334        crate::IntegrationFieldMappings::new(self.db.clone())
1335    }
1336
1337    /// Access customer operational topology snapshot operations.
1338    #[must_use]
1339    pub fn topology_snapshots(&self) -> crate::TopologySnapshots {
1340        crate::TopologySnapshots::new(self.db.clone())
1341    }
1342
1343    /// Access stock snapshot (point-in-time inventory) operations.
1344    #[must_use]
1345    pub fn stock_snapshots(&self) -> crate::StockSnapshots {
1346        crate::StockSnapshots::new(self.db.clone())
1347    }
1348
1349    /// Access product review operations.
1350    ///
1351    /// Provides review creation, moderation, summaries, and helpful/reported tracking.
1352    #[must_use]
1353    pub fn reviews(&self) -> Reviews {
1354        Reviews::new(self.db.clone())
1355    }
1356
1357    /// Access wishlist operations.
1358    ///
1359    /// Provides wishlist creation, item management, and customer wish tracking.
1360    #[must_use]
1361    pub fn wishlists(&self) -> Wishlists {
1362        Wishlists::new(self.db.clone())
1363    }
1364
1365    /// Access loyalty program operations.
1366    ///
1367    /// Provides loyalty program management, customer enrollment, points tracking,
1368    /// and reward catalog operations.
1369    #[must_use]
1370    pub fn loyalty(&self) -> Loyalty {
1371        Loyalty::new(self.db.clone())
1372    }
1373
1374    /// Access fraud detection operations.
1375    ///
1376    /// Provides fraud risk assessment, rule management, and manual review workflows.
1377    #[must_use]
1378    pub fn fraud(&self) -> Fraud {
1379        Fraud::new(self.db.clone())
1380    }
1381
1382    /// Access search configuration operations.
1383    ///
1384    /// Provides search configuration management including active config selection.
1385    #[must_use]
1386    pub fn search_config(&self) -> SearchConfigs {
1387        SearchConfigs::new(self.db.clone())
1388    }
1389
1390    /// Calculate and apply tax to a cart based on its shipping address.
1391    ///
1392    /// This method:
1393    /// 1. Retrieves the cart and its items
1394    /// 2. Uses the shipping address to determine tax jurisdiction
1395    /// 3. Calculates tax for each item based on jurisdiction and product category
1396    /// 4. Applies customer exemptions if applicable
1397    /// 5. Updates the cart with the calculated tax
1398    ///
1399    /// # Example
1400    ///
1401    /// ```rust,ignore
1402    /// use stateset_embedded::{Commerce, CreateCart, AddCartItem, CartAddress};
1403    /// use rust_decimal_macros::dec;
1404    /// use uuid::Uuid;
1405    ///
1406    /// let commerce = Commerce::new("./store.db")?;
1407    ///
1408    /// // Create a cart with items
1409    /// let cart = commerce.carts().create(CreateCart {
1410    ///     customer_email: Some("alice@example.com".into()),
1411    ///     ..Default::default()
1412    /// })?;
1413    ///
1414    /// commerce.carts().add_item(cart.id, AddCartItem {
1415    ///     sku: "SKU-001".into(),
1416    ///     name: "Widget".into(),
1417    ///     quantity: 2,
1418    ///     unit_price: dec!(29.99),
1419    ///     ..Default::default()
1420    /// })?;
1421    ///
1422    /// // Set shipping address
1423    /// commerce.carts().set_shipping_address(cart.id, CartAddress {
1424    ///     first_name: "Alice".into(),
1425    ///     last_name: "Smith".into(),
1426    ///     line1: "123 Main St".into(),
1427    ///     city: "Los Angeles".into(),
1428    ///     state: Some("CA".into()),
1429    ///     postal_code: "90210".into(),
1430    ///     country: "US".into(),
1431    ///     ..Default::default()
1432    /// })?;
1433    ///
1434    /// // Calculate and apply tax
1435    /// let result = commerce.calculate_cart_tax(cart.id)?;
1436    /// println!("Tax: ${}", result.total_tax);
1437    /// println!("Updated cart total: ${}", commerce.carts().get(cart.id)?.unwrap().grand_total);
1438    /// # Ok::<(), stateset_embedded::CommerceError>(())
1439    /// ```
1440    pub fn calculate_cart_tax(
1441        &self,
1442        cart_id: uuid::Uuid,
1443    ) -> stateset_core::Result<stateset_core::TaxCalculationResult> {
1444        use rust_decimal::Decimal;
1445        use stateset_core::{ProductTaxCategory, TaxAddress, TaxCalculationRequest, TaxLineItem};
1446
1447        let cart_id: stateset_core::CartId = cart_id.into();
1448
1449        // Get the cart
1450        let cart = self.carts().get(cart_id)?.ok_or(stateset_core::CommerceError::NotFound)?;
1451
1452        // Need a shipping address to calculate tax
1453        let shipping_address = cart.shipping_address.ok_or_else(|| {
1454            stateset_core::CommerceError::ValidationError(
1455                "Shipping address required to calculate tax".into(),
1456            )
1457        })?;
1458
1459        // Convert CartAddress to TaxAddress
1460        let tax_address = TaxAddress {
1461            country: shipping_address.country,
1462            state: shipping_address.state,
1463            city: Some(shipping_address.city),
1464            postal_code: Some(shipping_address.postal_code),
1465            line1: Some(shipping_address.line1),
1466            line2: shipping_address.line2,
1467        };
1468
1469        // Convert cart items to TaxLineItems
1470        let line_items: Vec<TaxLineItem> = cart
1471            .items
1472            .iter()
1473            .map(|item| {
1474                TaxLineItem {
1475                    id: item.id.to_string(),
1476                    sku: Some(item.sku.clone()),
1477                    product_id: item.product_id,
1478                    quantity: Decimal::from(item.quantity),
1479                    unit_price: item.unit_price,
1480                    discount_amount: item.discount_amount,
1481                    tax_category: ProductTaxCategory::Standard, // Default to standard, can be enhanced
1482                    tax_code: None,
1483                    description: Some(item.name.clone()),
1484                }
1485            })
1486            .collect();
1487
1488        // Build tax calculation request
1489        let request = TaxCalculationRequest {
1490            line_items,
1491            shipping_address: tax_address,
1492            customer_id: cart.customer_id.map(Into::into),
1493            currency: cart.currency,
1494            shipping_amount: Some(cart.shipping_amount),
1495            ..Default::default()
1496        };
1497
1498        // Calculate tax
1499        let result = self.tax().calculate(request)?;
1500
1501        // Apply tax to cart
1502        self.carts().set_tax(cart_id, result.total_tax)?;
1503
1504        Ok(result)
1505    }
1506
1507    /// Calculate and apply promotions to a cart.
1508    ///
1509    /// This method:
1510    /// 1. Retrieves the cart and its items
1511    /// 2. Finds all applicable automatic promotions
1512    /// 3. Validates any coupon codes applied to the cart
1513    /// 4. Calculates discounts respecting stacking rules
1514    /// 5. Updates the cart with the calculated discount
1515    ///
1516    /// # Example
1517    ///
1518    /// ```rust,ignore
1519    /// use stateset_embedded::{Commerce, CreateCart, AddCartItem};
1520    /// use rust_decimal_macros::dec;
1521    ///
1522    /// let commerce = Commerce::new("./store.db")?;
1523    ///
1524    /// // Create a cart with items
1525    /// let cart = commerce.carts().create(CreateCart {
1526    ///     customer_email: Some("alice@example.com".into()),
1527    ///     ..Default::default()
1528    /// })?;
1529    ///
1530    /// commerce.carts().add_item(cart.id, AddCartItem {
1531    ///     sku: "SKU-001".into(),
1532    ///     name: "Widget".into(),
1533    ///     quantity: 2,
1534    ///     unit_price: dec!(49.99),
1535    ///     ..Default::default()
1536    /// })?;
1537    ///
1538    /// // Apply a coupon code
1539    /// commerce.carts().apply_discount(cart.id, "SUMMER20")?;
1540    ///
1541    /// // Calculate and apply promotions
1542    /// let result = commerce.apply_cart_promotions(cart.id)?;
1543    /// println!("Discount: ${}", result.total_discount);
1544    /// println!("Applied promotions: {:?}", result.applied_promotions.len());
1545    ///
1546    /// // Cart now has discount applied
1547    /// let updated_cart = commerce.carts().get(cart.id)?.unwrap();
1548    /// println!("New total: ${}", updated_cart.grand_total);
1549    /// # Ok::<(), stateset_embedded::CommerceError>(())
1550    /// ```
1551    pub fn apply_cart_promotions(
1552        &self,
1553        cart_id: uuid::Uuid,
1554    ) -> stateset_core::Result<stateset_core::ApplyPromotionsResult> {
1555        use stateset_core::{
1556            ApplyPromotionsRequest, PromotionLineItem, UpdateCart, UpdateCartItem,
1557        };
1558
1559        let cart_id: stateset_core::CartId = cart_id.into();
1560
1561        // Get the cart
1562        let cart = self.carts().get(cart_id)?.ok_or(stateset_core::CommerceError::NotFound)?;
1563
1564        // Convert cart items to PromotionLineItems
1565        let line_items: Vec<PromotionLineItem> = cart
1566            .items
1567            .iter()
1568            .map(|item| {
1569                PromotionLineItem {
1570                    id: item.id.to_string(),
1571                    product_id: item.product_id,
1572                    variant_id: item.variant_id,
1573                    sku: Some(item.sku.clone()),
1574                    category_ids: vec![], // Could be enhanced to load from product
1575                    quantity: item.quantity,
1576                    unit_price: item.unit_price,
1577                    line_total: item.total,
1578                }
1579            })
1580            .collect();
1581
1582        // Build promotion request
1583        let coupon_codes = cart.coupon_code.map(|c| vec![c]).unwrap_or_default();
1584
1585        let request = ApplyPromotionsRequest {
1586            cart_id: Some(cart_id),
1587            customer_id: cart.customer_id,
1588            subtotal: cart.subtotal,
1589            shipping_amount: cart.shipping_amount,
1590            shipping_country: cart.shipping_address.as_ref().map(|a| a.country.clone()),
1591            shipping_state: cart.shipping_address.as_ref().and_then(|a| a.state.clone()),
1592            currency: cart.currency,
1593            coupon_codes,
1594            line_items,
1595            is_first_order: false, // Could check customer order history
1596        };
1597
1598        // Apply promotions
1599        let result = self.promotions().apply(request)?;
1600
1601        let discount_description = result
1602            .applied_promotions
1603            .iter()
1604            .map(|p| p.promotion_name.as_str())
1605            .collect::<Vec<_>>()
1606            .join(", ");
1607
1608        let discount_description =
1609            if discount_description.is_empty() { None } else { Some(discount_description) };
1610
1611        self.carts().update(
1612            cart_id,
1613            UpdateCart {
1614                discount_amount: Some(result.total_discount),
1615                discount_description,
1616                ..Default::default()
1617            },
1618        )?;
1619
1620        // Update individual item discounts if there are line item discounts
1621        for line_discount in &result.line_item_discounts {
1622            if let Ok(item_id) = line_discount.line_item_id.parse::<uuid::Uuid>() {
1623                self.carts().update_item(
1624                    item_id,
1625                    UpdateCartItem {
1626                        discount_amount: Some(line_discount.discount_amount),
1627                        ..Default::default()
1628                    },
1629                )?;
1630            }
1631        }
1632
1633        // Recalculate cart totals
1634        self.carts().recalculate(cart_id)?;
1635
1636        // Record promotion usage for tracking
1637        for applied in &result.applied_promotions {
1638            // Look up coupon_id if a coupon code was used
1639            let coupon_id = if let Some(ref code) = applied.coupon_code {
1640                self.promotions().get_coupon_by_code(code)?.map(|c| c.id)
1641            } else {
1642                None
1643            };
1644
1645            let _ = self.promotions().record_usage(
1646                applied.promotion_id,
1647                coupon_id,
1648                cart.customer_id,
1649                None, // order_id - will be set when order is created
1650                Some(cart_id),
1651                applied.discount_amount,
1652                cart.currency.as_str(),
1653            );
1654        }
1655
1656        Ok(result)
1657    }
1658}