...
This commit is contained in:
		
							
								
								
									
										48
									
								
								herodb/src/cmd/dbexample_biz/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								herodb/src/cmd/dbexample_biz/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
# Business Models Example
 | 
			
		||||
 | 
			
		||||
This example demonstrates the business models in HeroDB, showcasing a complete business transaction flow from product definition to payment processing.
 | 
			
		||||
 | 
			
		||||
## Features Demonstrated
 | 
			
		||||
 | 
			
		||||
1. **Product Definition**: Creating two types of server node products with different components and pricing
 | 
			
		||||
2. **Component Definition**: Defining the parts that make up each server node (CPU, RAM, Storage, GPU)
 | 
			
		||||
3. **Pricing Setup**: Setting up prices for products using the Currency model
 | 
			
		||||
4. **Product Availability**: Checking which products can be purchased based on their status and availability
 | 
			
		||||
5. **Sales Process**: Simulating a customer purchasing a product
 | 
			
		||||
6. **Invoice Generation**: Creating an invoice for the sale
 | 
			
		||||
7. **Payment Processing**: Processing a payment for the invoice and updating its status
 | 
			
		||||
 | 
			
		||||
## Business Flow
 | 
			
		||||
 | 
			
		||||
The example follows this business flow:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Define Products → Check Availability → Customer Purchase → Generate Invoice → Process Payment
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Models Used
 | 
			
		||||
 | 
			
		||||
- **Product & ProductComponent**: For defining server nodes and their components
 | 
			
		||||
- **Customer**: For representing the buyer
 | 
			
		||||
- **Sale & SaleItem**: For recording the purchase transaction
 | 
			
		||||
- **Invoice & InvoiceItem**: For billing the customer
 | 
			
		||||
- **Payment**: For recording the payment
 | 
			
		||||
 | 
			
		||||
## Running the Example
 | 
			
		||||
 | 
			
		||||
To run this example, use:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cargo run --bin dbexample_biz
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The output will show each step of the business process with relevant details.
 | 
			
		||||
 | 
			
		||||
## Key Concepts
 | 
			
		||||
 | 
			
		||||
- **Builder Pattern**: All models use builders for flexible object creation
 | 
			
		||||
- **Status Tracking**: Sales and invoices have status enums to track their state
 | 
			
		||||
- **Relationship Modeling**: The example shows how different business entities relate to each other
 | 
			
		||||
- **Financial Calculations**: Demonstrates tax and total calculations
 | 
			
		||||
 | 
			
		||||
This example provides a template for implementing business logic in your own applications using HeroDB.
 | 
			
		||||
							
								
								
									
										275
									
								
								herodb/src/cmd/dbexample_biz/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								herodb/src/cmd/dbexample_biz/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,275 @@
 | 
			
		||||
use chrono::{Duration, Utc};
 | 
			
		||||
use crate::models::biz::{
 | 
			
		||||
    Currency, CurrencyBuilder,
 | 
			
		||||
    Product, ProductBuilder, ProductComponent, ProductComponentBuilder, ProductType, ProductStatus,
 | 
			
		||||
    Sale, SaleBuilder, SaleItem, SaleItemBuilder, SaleStatus,
 | 
			
		||||
    Invoice, InvoiceBuilder, InvoiceItem, InvoiceItemBuilder, InvoiceStatus, Payment, PaymentStatus,
 | 
			
		||||
    Customer, CustomerBuilder,
 | 
			
		||||
};
 | 
			
		||||
use crate::db::base::SledModel;
 | 
			
		||||
 | 
			
		||||
/// This example demonstrates the business models in action:
 | 
			
		||||
/// 1. Defining products (2 types of server nodes)
 | 
			
		||||
/// 2. Defining components (parts of the nodes)
 | 
			
		||||
/// 3. Setting up pricing
 | 
			
		||||
/// 4. Creating a function to check which products can be bought
 | 
			
		||||
/// 5. Simulating a user buying a product
 | 
			
		||||
/// 6. Generating an invoice
 | 
			
		||||
/// 7. Simulating payment
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    println!("Business Models Example");
 | 
			
		||||
    println!("=======================\n");
 | 
			
		||||
 | 
			
		||||
    // Create a customer
 | 
			
		||||
    let customer = create_customer();
 | 
			
		||||
    println!("Created customer: {}", customer.name);
 | 
			
		||||
 | 
			
		||||
    // Define products (server nodes)
 | 
			
		||||
    let (standard_node, premium_node) = create_server_products();
 | 
			
		||||
    println!("Created server products:");
 | 
			
		||||
    println!("  - Standard Node: ${} {}", standard_node.price.amount, standard_node.price.currency_code);
 | 
			
		||||
    println!("  - Premium Node: ${} {}", premium_node.price.amount, premium_node.price.currency_code);
 | 
			
		||||
 | 
			
		||||
    // Check which products can be purchased
 | 
			
		||||
    println!("\nChecking which products can be purchased:");
 | 
			
		||||
    let purchasable_products = get_purchasable_products(&[&standard_node, &premium_node]);
 | 
			
		||||
    for product in purchasable_products {
 | 
			
		||||
        println!("  - {} is available for purchase", product.name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Simulate a user buying a product
 | 
			
		||||
    println!("\nSimulating purchase of a Premium Node:");
 | 
			
		||||
    let sale = create_sale(&customer, &premium_node);
 | 
			
		||||
    println!("  - Sale created with ID: {}", sale.id);
 | 
			
		||||
    println!("  - Total amount: ${} {}", sale.total_amount.amount, sale.total_amount.currency_code);
 | 
			
		||||
    
 | 
			
		||||
    // Generate an invoice
 | 
			
		||||
    println!("\nGenerating invoice:");
 | 
			
		||||
    let invoice = create_invoice(&customer, &sale);
 | 
			
		||||
    println!("  - Invoice created with ID: {}", invoice.id);
 | 
			
		||||
    println!("  - Total amount: ${} {}", invoice.total_amount.amount, invoice.total_amount.currency_code);
 | 
			
		||||
    println!("  - Due date: {}", invoice.due_date);
 | 
			
		||||
    println!("  - Status: {:?}", invoice.status);
 | 
			
		||||
    
 | 
			
		||||
    // Simulate payment
 | 
			
		||||
    println!("\nSimulating payment:");
 | 
			
		||||
    let paid_invoice = process_payment(invoice);
 | 
			
		||||
    println!("  - Payment processed");
 | 
			
		||||
    println!("  - New balance due: ${} {}", paid_invoice.balance_due.amount, paid_invoice.balance_due.currency_code);
 | 
			
		||||
    println!("  - Payment status: {:?}", paid_invoice.payment_status);
 | 
			
		||||
    println!("  - Invoice status: {:?}", paid_invoice.status);
 | 
			
		||||
    
 | 
			
		||||
    println!("\nBusiness transaction completed successfully!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create a customer for our example
 | 
			
		||||
fn create_customer() -> Customer {
 | 
			
		||||
    CustomerBuilder::new()
 | 
			
		||||
        .id(1)
 | 
			
		||||
        .name("TechCorp Inc.")
 | 
			
		||||
        .description("Enterprise technology company")
 | 
			
		||||
        .pubkey("tech-corp-public-key-123")
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create customer")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create two types of server node products with their components
 | 
			
		||||
fn create_server_products() -> (Product, Product) {
 | 
			
		||||
    // Create currency for pricing
 | 
			
		||||
    let usd = |amount| {
 | 
			
		||||
        CurrencyBuilder::new()
 | 
			
		||||
            .amount(amount)
 | 
			
		||||
            .currency_code("USD")
 | 
			
		||||
            .build()
 | 
			
		||||
            .expect("Failed to create currency")
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // Standard Node Components
 | 
			
		||||
    let cpu_standard = ProductComponentBuilder::new()
 | 
			
		||||
        .id(1)
 | 
			
		||||
        .name("CPU")
 | 
			
		||||
        .description("4-core CPU")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create CPU component");
 | 
			
		||||
        
 | 
			
		||||
    let ram_standard = ProductComponentBuilder::new()
 | 
			
		||||
        .id(2)
 | 
			
		||||
        .name("RAM")
 | 
			
		||||
        .description("16GB RAM")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create RAM component");
 | 
			
		||||
        
 | 
			
		||||
    let storage_standard = ProductComponentBuilder::new()
 | 
			
		||||
        .id(3)
 | 
			
		||||
        .name("Storage")
 | 
			
		||||
        .description("500GB SSD")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create Storage component");
 | 
			
		||||
    
 | 
			
		||||
    // Premium Node Components
 | 
			
		||||
    let cpu_premium = ProductComponentBuilder::new()
 | 
			
		||||
        .id(4)
 | 
			
		||||
        .name("CPU")
 | 
			
		||||
        .description("8-core CPU")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create CPU component");
 | 
			
		||||
        
 | 
			
		||||
    let ram_premium = ProductComponentBuilder::new()
 | 
			
		||||
        .id(5)
 | 
			
		||||
        .name("RAM")
 | 
			
		||||
        .description("32GB RAM")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create RAM component");
 | 
			
		||||
        
 | 
			
		||||
    let storage_premium = ProductComponentBuilder::new()
 | 
			
		||||
        .id(6)
 | 
			
		||||
        .name("Storage")
 | 
			
		||||
        .description("1TB SSD")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create Storage component");
 | 
			
		||||
        
 | 
			
		||||
    let gpu_premium = ProductComponentBuilder::new()
 | 
			
		||||
        .id(7)
 | 
			
		||||
        .name("GPU")
 | 
			
		||||
        .description("Dedicated GPU")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create GPU component");
 | 
			
		||||
    
 | 
			
		||||
    // Create Standard Node Product
 | 
			
		||||
    let standard_node = ProductBuilder::new()
 | 
			
		||||
        .id(1)
 | 
			
		||||
        .name("Standard Server Node")
 | 
			
		||||
        .description("Basic server node for general workloads")
 | 
			
		||||
        .price(usd(99.99))
 | 
			
		||||
        .type_(ProductType::Product)
 | 
			
		||||
        .category("Servers")
 | 
			
		||||
        .status(ProductStatus::Available)
 | 
			
		||||
        .max_amount(100)
 | 
			
		||||
        .validity_days(365)
 | 
			
		||||
        .add_component(cpu_standard)
 | 
			
		||||
        .add_component(ram_standard)
 | 
			
		||||
        .add_component(storage_standard)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create Standard Node product");
 | 
			
		||||
    
 | 
			
		||||
    // Create Premium Node Product
 | 
			
		||||
    let premium_node = ProductBuilder::new()
 | 
			
		||||
        .id(2)
 | 
			
		||||
        .name("Premium Server Node")
 | 
			
		||||
        .description("High-performance server node for demanding workloads")
 | 
			
		||||
        .price(usd(199.99))
 | 
			
		||||
        .type_(ProductType::Product)
 | 
			
		||||
        .category("Servers")
 | 
			
		||||
        .status(ProductStatus::Available)
 | 
			
		||||
        .max_amount(50)
 | 
			
		||||
        .validity_days(365)
 | 
			
		||||
        .add_component(cpu_premium)
 | 
			
		||||
        .add_component(ram_premium)
 | 
			
		||||
        .add_component(storage_premium)
 | 
			
		||||
        .add_component(gpu_premium)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create Premium Node product");
 | 
			
		||||
    
 | 
			
		||||
    (standard_node, premium_node)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Check which products can be purchased
 | 
			
		||||
fn get_purchasable_products<'a>(products: &[&'a Product]) -> Vec<&'a Product> {
 | 
			
		||||
    products.iter()
 | 
			
		||||
        .filter(|p| p.is_purchasable())
 | 
			
		||||
        .copied()
 | 
			
		||||
        .collect()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create a sale for a customer buying a product
 | 
			
		||||
fn create_sale(customer: &Customer, product: &Product) -> Sale {
 | 
			
		||||
    let now = Utc::now();
 | 
			
		||||
    let active_till = now + Duration::days(365);
 | 
			
		||||
    
 | 
			
		||||
    // Create a sale item for the product
 | 
			
		||||
    let sale_item = SaleItemBuilder::new()
 | 
			
		||||
        .id(1)
 | 
			
		||||
        .sale_id(1)
 | 
			
		||||
        .product_id(product.id as u32)
 | 
			
		||||
        .name(product.name.clone())
 | 
			
		||||
        .description(product.description.clone())
 | 
			
		||||
        .comments("Customer requested expedited setup")
 | 
			
		||||
        .quantity(1)
 | 
			
		||||
        .unit_price(product.price.clone())
 | 
			
		||||
        .tax_rate(10.0) // 10% tax rate
 | 
			
		||||
        .active_till(active_till)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create sale item");
 | 
			
		||||
    
 | 
			
		||||
    // Create the sale
 | 
			
		||||
    let sale = SaleBuilder::new()
 | 
			
		||||
        .id(1)
 | 
			
		||||
        .company_id(101) // Assuming company ID 101
 | 
			
		||||
        .customer_id(customer.id)
 | 
			
		||||
        .buyer_name(customer.name.clone())
 | 
			
		||||
        .buyer_email("contact@techcorp.com") // Example email
 | 
			
		||||
        .currency_code(product.price.currency_code.clone())
 | 
			
		||||
        .status(SaleStatus::Completed)
 | 
			
		||||
        .add_item(sale_item)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create sale");
 | 
			
		||||
    
 | 
			
		||||
    sale
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create an invoice for a sale
 | 
			
		||||
fn create_invoice(customer: &Customer, sale: &Sale) -> Invoice {
 | 
			
		||||
    let now = Utc::now();
 | 
			
		||||
    let due_date = now + Duration::days(30); // Due in 30 days
 | 
			
		||||
    
 | 
			
		||||
    // Create an invoice item for the sale
 | 
			
		||||
    let invoice_item = InvoiceItemBuilder::new()
 | 
			
		||||
        .id(1)
 | 
			
		||||
        .invoice_id(1)
 | 
			
		||||
        .description(format!("Purchase of {}", sale.items[0].name))
 | 
			
		||||
        .amount(sale.total_amount.clone())
 | 
			
		||||
        .sale_id(sale.id)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create invoice item");
 | 
			
		||||
    
 | 
			
		||||
    // Create the invoice
 | 
			
		||||
    let invoice = InvoiceBuilder::new()
 | 
			
		||||
        .id(1)
 | 
			
		||||
        .customer_id(customer.id)
 | 
			
		||||
        .currency_code(sale.total_amount.currency_code.clone())
 | 
			
		||||
        .status(InvoiceStatus::Sent)
 | 
			
		||||
        .issue_date(now)
 | 
			
		||||
        .due_date(due_date)
 | 
			
		||||
        .add_item(invoice_item)
 | 
			
		||||
        .build()
 | 
			
		||||
        .expect("Failed to create invoice");
 | 
			
		||||
    
 | 
			
		||||
    invoice
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Process a payment for an invoice
 | 
			
		||||
fn process_payment(mut invoice: Invoice) -> Invoice {
 | 
			
		||||
    // Create a payment for the full amount
 | 
			
		||||
    let payment = Payment::new(
 | 
			
		||||
        invoice.total_amount.clone(),
 | 
			
		||||
        "Credit Card".to_string(),
 | 
			
		||||
        "Payment received via credit card ending in 1234".to_string()
 | 
			
		||||
    );
 | 
			
		||||
    
 | 
			
		||||
    // Add the payment to the invoice
 | 
			
		||||
    invoice.add_payment(payment);
 | 
			
		||||
    
 | 
			
		||||
    // The invoice should now be marked as paid
 | 
			
		||||
    assert_eq!(invoice.payment_status, PaymentStatus::Paid);
 | 
			
		||||
    assert_eq!(invoice.status, InvoiceStatus::Paid);
 | 
			
		||||
    
 | 
			
		||||
    invoice
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								herodb/src/cmd/dbexample_biz/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								herodb/src/cmd/dbexample_biz/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
//! Business example for HeroDB
 | 
			
		||||
//!
 | 
			
		||||
//! This module demonstrates business models in action,
 | 
			
		||||
//! including products, sales, invoices, and payments.
 | 
			
		||||
 | 
			
		||||
// Re-export the main function
 | 
			
		||||
pub use self::main::*;
 | 
			
		||||
 | 
			
		||||
// Include the main module
 | 
			
		||||
mod main;
 | 
			
		||||
							
								
								
									
										7
									
								
								herodb/src/cmd/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								herodb/src/cmd/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
//! Command examples for HeroDB
 | 
			
		||||
//!
 | 
			
		||||
//! This module contains various example commands and applications
 | 
			
		||||
//! that demonstrate how to use HeroDB in different scenarios.
 | 
			
		||||
 | 
			
		||||
// Export the example modules
 | 
			
		||||
pub mod dbexample_biz;
 | 
			
		||||
@@ -7,7 +7,9 @@
 | 
			
		||||
pub mod db;
 | 
			
		||||
pub mod error;
 | 
			
		||||
pub mod models;
 | 
			
		||||
pub mod rhaiengine;
 | 
			
		||||
// Temporarily commented out due to compilation errors
 | 
			
		||||
// pub mod rhaiengine;
 | 
			
		||||
pub mod cmd;
 | 
			
		||||
 | 
			
		||||
// Re-exports
 | 
			
		||||
pub use error::Error;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								herodb/src/rhaiengine/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								herodb/src/rhaiengine/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
//! Rhai Engine module for scripting support
 | 
			
		||||
//!
 | 
			
		||||
//! This module provides integration with the Rhai scripting language.
 | 
			
		||||
 | 
			
		||||
// Re-export the engine module
 | 
			
		||||
pub mod engine;
 | 
			
		||||
pub use engine::*;
 | 
			
		||||
		Reference in New Issue
	
	Block a user