use chrono::{DateTime, Duration, Utc}; use serde::{Deserialize, Serialize}; /// This example demonstrates 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!"); } // ===== Model Definitions ===== // Currency represents a monetary value with amount and currency code #[derive(Debug, Clone, Serialize, Deserialize)] struct Currency { amount: f64, currency_code: String, } // Customer represents a customer who can purchase products #[derive(Debug, Clone, Serialize, Deserialize)] struct Customer { id: u32, name: String, description: String, pubkey: String, } // ProductType represents the type of a product #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] enum ProductType { Product, Service, } // ProductStatus represents the status of a product #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] enum ProductStatus { Available, Unavailable, } // ProductComponent represents a component of a product #[derive(Debug, Clone, Serialize, Deserialize)] struct ProductComponent { id: i64, name: String, description: String, quantity: i64, } // Product represents a product or service offered #[derive(Debug, Clone, Serialize, Deserialize)] struct Product { id: i64, name: String, description: String, price: Currency, type_: ProductType, category: String, status: ProductStatus, max_amount: i64, purchase_till: DateTime, active_till: DateTime, components: Vec, } // SaleStatus represents the status of a sale #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] enum SaleStatus { Pending, Completed, Cancelled, } // SaleItem represents an item in a sale #[derive(Debug, Clone, Serialize, Deserialize)] struct SaleItem { id: u32, sale_id: u32, product_id: u32, name: String, description: String, comments: String, quantity: i32, unit_price: Currency, subtotal: Currency, tax_rate: f64, tax_amount: Currency, active_till: DateTime, } // Sale represents a sale of products or services #[derive(Debug, Clone, Serialize, Deserialize)] struct Sale { id: u32, company_id: u32, customer_id: u32, buyer_name: String, buyer_email: String, subtotal_amount: Currency, tax_amount: Currency, total_amount: Currency, status: SaleStatus, service_id: Option, sale_date: DateTime, items: Vec, } // InvoiceStatus represents the status of an invoice #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] enum InvoiceStatus { Draft, Sent, Paid, Overdue, Cancelled, } // PaymentStatus represents the payment status of an invoice #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] enum PaymentStatus { Unpaid, PartiallyPaid, Paid, } // Payment represents a payment made against an invoice #[derive(Debug, Clone, Serialize, Deserialize)] struct Payment { amount: Currency, date: DateTime, method: String, comment: String, } // InvoiceItem represents an item in an invoice #[derive(Debug, Clone, Serialize, Deserialize)] struct InvoiceItem { id: u32, invoice_id: u32, description: String, amount: Currency, sale_id: Option, } // Invoice represents an invoice sent to a customer #[derive(Debug, Clone, Serialize, Deserialize)] struct Invoice { id: u32, customer_id: u32, total_amount: Currency, balance_due: Currency, status: InvoiceStatus, payment_status: PaymentStatus, issue_date: DateTime, due_date: DateTime, items: Vec, payments: Vec, } // ===== Implementation Functions ===== // Create a customer for our example fn create_customer() -> Customer { Customer { id: 1, name: "TechCorp Inc.".to_string(), description: "Enterprise technology company".to_string(), pubkey: "tech-corp-public-key-123".to_string(), } } // Create two types of server node products with their components fn create_server_products() -> (Product, Product) { let now = Utc::now(); // Create currency for pricing let usd = |amount| { Currency { amount, currency_code: "USD".to_string(), } }; // Standard Node Components let cpu_standard = ProductComponent { id: 1, name: "CPU".to_string(), description: "4-core CPU".to_string(), quantity: 1, }; let ram_standard = ProductComponent { id: 2, name: "RAM".to_string(), description: "16GB RAM".to_string(), quantity: 1, }; let storage_standard = ProductComponent { id: 3, name: "Storage".to_string(), description: "500GB SSD".to_string(), quantity: 1, }; // Premium Node Components let cpu_premium = ProductComponent { id: 4, name: "CPU".to_string(), description: "8-core CPU".to_string(), quantity: 1, }; let ram_premium = ProductComponent { id: 5, name: "RAM".to_string(), description: "32GB RAM".to_string(), quantity: 1, }; let storage_premium = ProductComponent { id: 6, name: "Storage".to_string(), description: "1TB SSD".to_string(), quantity: 1, }; let gpu_premium = ProductComponent { id: 7, name: "GPU".to_string(), description: "Dedicated GPU".to_string(), quantity: 1, }; // Create Standard Node Product let standard_node = Product { id: 1, name: "Standard Server Node".to_string(), description: "Basic server node for general workloads".to_string(), price: usd(99.99), type_: ProductType::Product, category: "Servers".to_string(), status: ProductStatus::Available, max_amount: 100, purchase_till: now + Duration::days(365), active_till: now + Duration::days(365), components: vec![cpu_standard, ram_standard, storage_standard], }; // Create Premium Node Product let premium_node = Product { id: 2, name: "Premium Server Node".to_string(), description: "High-performance server node for demanding workloads".to_string(), price: usd(199.99), type_: ProductType::Product, category: "Servers".to_string(), status: ProductStatus::Available, max_amount: 50, purchase_till: now + Duration::days(365), active_till: now + Duration::days(365), components: vec![cpu_premium, ram_premium, storage_premium, gpu_premium], }; (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.status == ProductStatus::Available && Utc::now() <= p.purchase_till) .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 = SaleItem { id: 1, sale_id: 1, product_id: product.id as u32, name: product.name.clone(), description: product.description.clone(), comments: "Customer requested expedited setup".to_string(), quantity: 1, unit_price: product.price.clone(), subtotal: Currency { amount: product.price.amount * 1.0, currency_code: product.price.currency_code.clone(), }, tax_rate: 10.0, // 10% tax rate tax_amount: Currency { amount: product.price.amount * 0.1, currency_code: product.price.currency_code.clone(), }, active_till, }; // Calculate totals let subtotal = sale_item.subtotal.clone(); let tax_amount = sale_item.tax_amount.clone(); let total_amount = Currency { amount: subtotal.amount + tax_amount.amount, currency_code: subtotal.currency_code.clone(), }; // Create the sale Sale { id: 1, company_id: 101, // Assuming company ID 101 customer_id: customer.id, buyer_name: customer.name.clone(), buyer_email: "contact@techcorp.com".to_string(), // Example email subtotal_amount: subtotal, tax_amount, total_amount, status: SaleStatus::Completed, service_id: None, sale_date: now, items: vec![sale_item], } } // 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 = InvoiceItem { id: 1, invoice_id: 1, description: format!("Purchase of {}", sale.items[0].name), amount: sale.total_amount.clone(), sale_id: Some(sale.id), }; // Create the invoice Invoice { id: 1, customer_id: customer.id, total_amount: sale.total_amount.clone(), balance_due: sale.total_amount.clone(), status: InvoiceStatus::Sent, payment_status: PaymentStatus::Unpaid, issue_date: now, due_date, items: vec![invoice_item], payments: Vec::new(), } } // Process a payment for an invoice fn process_payment(mut invoice: Invoice) -> Invoice { // Create a payment for the full amount let payment = Payment { amount: invoice.total_amount.clone(), date: Utc::now(), method: "Credit Card".to_string(), comment: "Payment received via credit card ending in 1234".to_string(), }; // Add the payment to the invoice invoice.payments.push(payment); // Update the balance due invoice.balance_due.amount = 0.0; // Update the payment status invoice.payment_status = PaymentStatus::Paid; invoice.status = InvoiceStatus::Paid; invoice }