db/herodb_old/src/models/biz
2025-04-22 12:53:17 +04:00
..
rhai ... 2025-04-22 12:53:17 +04:00
contract.rs ... 2025-04-22 12:53:17 +04:00
currency.rs ... 2025-04-22 12:53:17 +04:00
customer.rs ... 2025-04-22 12:53:17 +04:00
exchange_rate.rs ... 2025-04-22 12:53:17 +04:00
invoice.rs ... 2025-04-22 12:53:17 +04:00
lib.rs ... 2025-04-22 12:53:17 +04:00
mod.rs ... 2025-04-22 12:53:17 +04:00
product.rs ... 2025-04-22 12:53:17 +04:00
README.md ... 2025-04-22 12:53:17 +04:00
sale.rs ... 2025-04-22 12:53:17 +04:00
service.rs ... 2025-04-22 12:53:17 +04:00

Business Models

This directory contains the core business models used throughout the application for representing essential business objects like products, sales, and currency.

                                         ┌─────────────┐
                                         │  Customer   │
                                         └──────┬──────┘
                                                │
                                                ▼
┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Currency  │◄────┤   Product   │◄────┤             │     │             │
└─────────────┘     └─────────────┘     │             │     │             │
                          ▲             │  SaleItem   │◄────┤    Sale     │
                          │             │             │     │             │
                    ┌─────┴──────────┐  │             │     │             │
                    │ProductComponent│  └─────────────┘     └──────┬──────┘
                    └────────────────┘          ▲                  │
                                               /                   │
┌─────────────┐     ┌─────────────┐          /                    │
│   Currency  │◄────┤   Service   │◄────────/                     │
└─────────────┘     └─────────────┘                               │
                                                                  │
                                                                  │
                                                                  ▼
                                        ┌─────────────┐     ┌─────────────┐
                                        │ InvoiceItem │◄────┤   Invoice   │
                                        └─────────────┘     └─────────────┘

Business Logic Relationships

  • Customer: The entity purchasing products or services
  • Product/Service: Defines what is being sold, including its base price
    • Can be marked as a template (is_template=true) to create copies for actual sales
  • Sale: Represents the transaction of selling products/services to customers, including tax calculations
    • Contains SaleItems that can be linked to either Products or Services
  • SaleItem: Represents an item within a sale
    • Can be linked to either a Product or a Service (via product_id or service_id)
  • Service: Represents an ongoing service provided to a customer
    • Created from a Product template when the product type is Service
  • Invoice: Represents the billing document for a sale, with payment tracking
    • Created from a Sale object to handle billing and payment tracking

Root Objects

  • Root objects are the ones stored directly in the DB
  • Root Objects are:
    • Customer
    • Currency
    • Product
    • Sale
    • Service
    • Invoice

Models

Currency (Root Object)

Represents a monetary value with an amount and currency code.

Properties:

  • amount: f64 - The monetary amount
  • currency_code: String - The currency code (e.g., "USD", "EUR")

Builder:

  • CurrencyBuilder - Provides a fluent interface for creating Currency instances

Customer (Root Object)

Represents a customer who can purchase products or services.

Properties:

  • id: u32 - Unique identifier
  • name: String - Customer name
  • description: String - Customer description
  • pubkey: String - Customer's public key
  • contact_ids: Vec - List of contact IDs
  • created_at: DateTime - Creation timestamp
  • updated_at: DateTime - Last update timestamp

Methods:

  • add_contact() - Adds a contact ID to the customer
  • remove_contact() - Removes a contact ID from the customer

Product

ProductType Enum

Categorizes products:

  • Product - Physical product
  • Service - Non-physical service

ProductStatus Enum

Tracks product availability:

  • Available - Product can be purchased
  • Unavailable - Product cannot be purchased

ProductComponent

Represents a component part of a product.

Properties:

  • id: u32 - Unique identifier
  • name: String - Component name
  • description: String - Component description
  • quantity: i32 - Number of this component
  • created_at: DateTime - Creation timestamp
  • updated_at: DateTime - Last update timestamp

Builder:

  • ProductComponentBuilder - Provides a fluent interface for creating ProductComponent instances

Product (Root Object)

Represents a product or service offered.

Properties:

  • id: i64 - Unique identifier
  • name: String - Product name
  • description: String - Product description
  • price: Currency - Product price
  • type_: ProductType - Product or Service
  • category: String - Product category
  • status: ProductStatus - Available or Unavailable
  • created_at: DateTime - Creation timestamp
  • updated_at: DateTime - Last update timestamp
  • max_amount: i64 - Maximum quantity available
  • purchase_till: DateTime - Deadline for purchasing
  • active_till: DateTime - When product/service expires
  • components: Vec - List of product components
  • is_template: bool - Whether this is a template product (to be added)

Methods:

  • add_component() - Adds a component to this product
  • set_purchase_period() - Updates purchase availability timeframe
  • set_active_period() - Updates active timeframe
  • is_purchasable() - Checks if product is available for purchase
  • is_active() - Checks if product is still active

Builder:

  • ProductBuilder - Provides a fluent interface for creating Product instances

Database Implementation:

  • Implements Storable trait for serialization
  • Implements SledModel trait with:
    • get_id() - Returns the ID as a string
    • db_prefix() - Returns "product" as the database prefix

Service (Root Object)

BillingFrequency Enum

Defines how often a service is billed:

  • Hourly - Billed by the hour
  • Daily - Billed daily
  • Weekly - Billed weekly
  • Monthly - Billed monthly
  • Yearly - Billed yearly

ServiceStatus Enum

Tracks the status of a service:

  • Active - Service is currently active
  • Paused - Service is temporarily paused
  • Cancelled - Service has been cancelled
  • Completed - Service has been completed

ServiceItem

Represents an item within a service.

Properties:

  • id: u32 - Unique identifier
  • service_id: u32 - Parent service ID
  • product_id: u32 - ID of the product this service is based on
  • name: String - Service name
  • description: String - Detailed description of the service item
  • comments: String - Additional notes or comments about the service item
  • quantity: i32 - Number of units
  • unit_price: Currency - Price per unit
  • subtotal: Currency - Total price before tax
  • tax_rate: f64 - Tax rate as a percentage
  • tax_amount: Currency - Calculated tax amount
  • is_taxable: bool - Whether this item is taxable
  • active_till: DateTime - When service expires

Service

Represents an ongoing service provided to a customer.

Properties:

  • id: u32 - Unique identifier
  • customer_id: u32 - ID of the customer receiving the service
  • total_amount: Currency - Total service amount including tax
  • status: ServiceStatus - Current service status
  • billing_frequency: BillingFrequency - How often the service is billed
  • service_date: DateTime - When service started
  • created_at: DateTime - Creation timestamp
  • updated_at: DateTime - Last update timestamp
  • items: Vec - List of items in the service
  • is_template: bool - Whether this is a template service (to be added)

Methods:

  • add_item() - Adds an item to the service and updates total
  • calculate_total() - Recalculates the total amount
  • update_status() - Updates the status of the service

Sale

SaleStatus Enum

Tracks the status of a sale:

  • Pending - Sale is in progress
  • Completed - Sale has been finalized
  • Cancelled - Sale has been cancelled

SaleItem

Represents an item within a sale.

Properties:

  • id: u32 - Unique identifier
  • sale_id: u32 - Parent sale ID
  • product_id: Option - ID of the product sold (if this is a product sale)
  • service_id: Option - ID of the service sold (if this is a service sale)
  • name: String - Product/service name at time of sale
  • description: String - Detailed description of the item
  • comments: String - Additional notes or comments about the item
  • quantity: i32 - Number of items purchased
  • unit_price: Currency - Price per unit
  • subtotal: Currency - Total price for this item before tax (calculated)
  • tax_rate: f64 - Tax rate as a percentage (e.g., 20.0 for 20%)
  • tax_amount: Currency - Calculated tax amount for this item
  • active_till: DateTime - When item/service expires

Methods:

  • total_with_tax() - Returns the total amount including tax

Builder:

  • SaleItemBuilder - Provides a fluent interface for creating SaleItem instances

Sale (Root Object)

Represents a complete sale transaction.

Properties:

  • id: u32 - Unique identifier
  • company_id: u32 - ID of the company making the sale
  • customer_id: u32 - ID of the customer making the purchase (to be added)
  • buyer_name: String - Name of the buyer
  • buyer_email: String - Email of the buyer
  • subtotal_amount: Currency - Total sale amount before tax
  • tax_amount: Currency - Total tax amount for the sale
  • total_amount: Currency - Total sale amount including tax
  • status: SaleStatus - Current sale status
  • service_id: Option - ID of the service created from this sale (to be added)
  • sale_date: DateTime - When sale occurred
  • created_at: DateTime - Creation timestamp
  • updated_at: DateTime - Last update timestamp
  • items: Vec - List of items in the sale

Methods:

  • add_item() - Adds an item to the sale and updates totals
  • update_status() - Updates the status of the sale
  • recalculate_totals() - Recalculates all totals based on items
  • create_service() - Creates a service from this sale (to be added)

Builder:

  • SaleBuilder - Provides a fluent interface for creating Sale instances

Database Implementation:

  • Implements Storable trait for serialization
  • Implements SledModel trait with:
    • get_id() - Returns the ID as a string
    • db_prefix() - Returns "sale" as the database prefix

Usage Examples

Creating a Currency

let price = CurrencyBuilder::new()
    .amount(29.99)
    .currency_code("USD")
    .build()
    .expect("Failed to build currency");

Creating a Product

// Create a currency using the builder
let price = CurrencyBuilder::new()
    .amount(29.99)
    .currency_code("USD")
    .build()
    .expect("Failed to build currency");

// Create a component using the builder
let component = ProductComponentBuilder::new()
    .id(1)
    .name("Basic Support")
    .description("24/7 email support")
    .quantity(1)
    .build()
    .expect("Failed to build product component");

// Create a product using the builder
let product = ProductBuilder::new()
    .id(1)
    .name("Premium Service")
    .description("Our premium service offering")
    .price(price)
    .type_(ProductType::Service)
    .category("Services")
    .status(ProductStatus::Available)
    .max_amount(100)
    .validity_days(30)
    .add_component(component)
    .build()
    .expect("Failed to build product");

Creating a Sale

let now = Utc::now();

// Create a currency using the builder
let unit_price = CurrencyBuilder::new()
    .amount(29.99)
    .currency_code("USD")
    .build()
    .expect("Failed to build currency");

// Create a sale item using the builder
let item = SaleItemBuilder::new()
    .id(1)
    .sale_id(1)
    .product_id(1)
    .name("Premium Service")
    .quantity(1)
    .unit_price(unit_price)
    .tax_rate(20.0) // 20% tax rate
    .active_till(now + Duration::days(30))
    .build()
    .expect("Failed to build sale item");

// Create a sale using the builder
let mut sale = SaleBuilder::new()
    .id(1)
    .company_id(101)
    .buyer_name("John Doe")
    .buyer_email("john.doe@example.com")
    .currency_code("USD")
    .status(SaleStatus::Pending)
    .add_item(item)
    .build()
    .expect("Failed to build sale");

// Update the sale status
sale.update_status(SaleStatus::Completed);

// The sale now contains:
// - subtotal_amount: The sum of all items before tax
// - tax_amount: The sum of all tax amounts
// - total_amount: The total including tax

Relationship Between Sale and Invoice

The Sale model represents what is sold to a customer (products or services), including tax calculations. The Invoice model represents the billing document for that sale.

An InvoiceItem can be linked to a Sale via the sale_id field, establishing a connection between what was sold and how it's billed.

// Create an invoice item linked to a sale
let invoice_item = InvoiceItemBuilder::new()
    .id(1)
    .invoice_id(1)
    .description("Premium Service")
    .amount(sale.total_amount.clone()) // Use the total amount from the sale
    .sale_id(sale.id) // Link to the sale
    .build()
    .expect("Failed to build invoice item");

Database Operations

The library provides model-specific convenience methods for common database operations:

// Insert a product
db.insert_product(&product).expect("Failed to insert product");

// Retrieve a product by ID
let retrieved_product = db.get_product(1).expect("Failed to retrieve product");

// List all products
let all_products = db.list_products().expect("Failed to list products");

// Delete a product
db.delete_product(1).expect("Failed to delete product");

These methods are available for all root objects:

  • insert_product, get_product, delete_product, list_products for Product
  • insert_currency, get_currency, delete_currency, list_currencies for Currency
  • insert_sale, get_sale, delete_sale, list_sales for Sale
  • insert_service, get_service, delete_service, list_services for Service
  • insert_invoice, get_invoice, delete_invoice, list_invoices for Invoice
  • insert_customer, get_customer, delete_customer, list_customers for Customer

Invoice (Root Object)

InvoiceStatus Enum

Tracks the status of an invoice:

  • Draft - Invoice is in draft state
  • Sent - Invoice has been sent to the customer
  • Paid - Invoice has been paid
  • Overdue - Invoice is past due date
  • Cancelled - Invoice has been cancelled

PaymentStatus Enum

Tracks the payment status of an invoice:

  • Unpaid - Invoice has not been paid
  • PartiallyPaid - Invoice has been partially paid
  • Paid - Invoice has been fully paid

Payment

Represents a payment made against an invoice.

Properties:

  • amount: Currency - Payment amount
  • date: DateTime - Payment date
  • method: String - Payment method
  • comment: String - Payment comment

InvoiceItem

Represents an item in an invoice.

Properties:

  • id: u32 - Unique identifier
  • invoice_id: u32 - Parent invoice ID
  • description: String - Item description
  • amount: Currency - Item amount
  • service_id: Option - ID of the service this item is for
  • sale_id: Option - ID of the sale this item is for

Methods:

  • link_to_service() - Links the invoice item to a service
  • link_to_sale() - Links the invoice item to a sale

Invoice

Represents an invoice sent to a customer.

Properties:

  • id: u32 - Unique identifier
  • customer_id: u32 - ID of the customer being invoiced
  • total_amount: Currency - Total invoice amount
  • balance_due: Currency - Amount still due
  • status: InvoiceStatus - Current invoice status
  • payment_status: PaymentStatus - Current payment status
  • issue_date: DateTime - When invoice was issued
  • due_date: DateTime - When payment is due
  • created_at: DateTime - Creation timestamp
  • updated_at: DateTime - Last update timestamp
  • items: Vec - List of items in the invoice
  • payments: Vec - List of payments made

Methods:

  • add_item() - Adds an item to the invoice
  • calculate_total() - Calculates the total amount
  • add_payment() - Adds a payment to the invoice
  • calculate_balance() - Calculates the balance due
  • update_payment_status() - Updates the payment status
  • update_status() - Updates the status of the invoice
  • is_overdue() - Checks if the invoice is overdue
  • check_if_overdue() - Marks the invoice as overdue if past due date

Relationships Between Models

Product/Service Templates and Instances

Products and Services can be marked as templates (is_template=true). When a customer purchases a product or service, a copy is created from the template with the specific details of what was sold.

Sale to Service Relationship

A SaleItem can be directly linked to a Service via the service_id field. This allows for selling existing services or creating new services as part of a sale:

// Create a SaleItem linked to a service
let sale_item = SaleItemBuilder::new()
    .id(1)
    .sale_id(1)
    .service_id(Some(42))  // Link to service with ID 42
    .product_id(None)      // No product link since this is a service
    .name("Premium Support")
    .quantity(1)
    .unit_price(unit_price)
    .tax_rate(20.0)
    .active_till(now + Duration::days(30))
    .build()
    .expect("Failed to build sale item");

Sale to Invoice Relationship

An Invoice is created from a Sale to handle billing and payment tracking:

// Create an invoice from a sale
let invoice = Invoice::from_sale(
    invoice_id,
    sale,
    due_date
);

Customer-Centric View

The models allow tracking all customer interactions:

  • What products/services they've purchased (via Sale records)
  • What ongoing services they have (via Service records)
  • What they've been invoiced for (via Invoice records)
  • What they've paid (via Payment records in Invoices)
// Get all sales for a customer
let customer_sales = db.list_sales_by_customer(customer_id);

// Get all services for a customer
let customer_services = db.list_services_by_customer(customer_id);

// Get all invoices for a customer
let customer_invoices = db.list_invoices_by_customer(customer_id);