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 
 - Can be marked as a template (
 - 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 amountcurrency_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 identifiername: String - Customer namedescription: String - Customer descriptionpubkey: String - Customer's public keycontact_ids: Vec - List of contact IDscreated_at: DateTime - Creation timestampupdated_at: DateTime - Last update timestamp
Methods:
add_contact()- Adds a contact ID to the customerremove_contact()- Removes a contact ID from the customer
Product
ProductType Enum
Categorizes products:
Product- Physical productService- Non-physical service
ProductStatus Enum
Tracks product availability:
Available- Product can be purchasedUnavailable- Product cannot be purchased
ProductComponent
Represents a component part of a product.
Properties:
id: u32 - Unique identifiername: String - Component namedescription: String - Component descriptionquantity: i32 - Number of this componentcreated_at: DateTime - Creation timestampupdated_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 identifiername: String - Product namedescription: String - Product descriptionprice: Currency - Product pricetype_: ProductType - Product or Servicecategory: String - Product categorystatus: ProductStatus - Available or Unavailablecreated_at: DateTime - Creation timestampupdated_at: DateTime - Last update timestampmax_amount: i64 - Maximum quantity availablepurchase_till: DateTime - Deadline for purchasingactive_till: DateTime - When product/service expirescomponents: Vec - List of product componentsis_template: bool - Whether this is a template product (to be added)
Methods:
add_component()- Adds a component to this productset_purchase_period()- Updates purchase availability timeframeset_active_period()- Updates active timeframeis_purchasable()- Checks if product is available for purchaseis_active()- Checks if product is still active
Builder:
ProductBuilder- Provides a fluent interface for creating Product instances
Database Implementation:
- Implements 
Storabletrait for serialization - Implements 
SledModeltrait with:get_id()- Returns the ID as a stringdb_prefix()- Returns "product" as the database prefix
 
Service (Root Object)
BillingFrequency Enum
Defines how often a service is billed:
Hourly- Billed by the hourDaily- Billed dailyWeekly- Billed weeklyMonthly- Billed monthlyYearly- Billed yearly
ServiceStatus Enum
Tracks the status of a service:
Active- Service is currently activePaused- Service is temporarily pausedCancelled- Service has been cancelledCompleted- Service has been completed
ServiceItem
Represents an item within a service.
Properties:
id: u32 - Unique identifierservice_id: u32 - Parent service IDproduct_id: u32 - ID of the product this service is based onname: String - Service namedescription: String - Detailed description of the service itemcomments: String - Additional notes or comments about the service itemquantity: i32 - Number of unitsunit_price: Currency - Price per unitsubtotal: Currency - Total price before taxtax_rate: f64 - Tax rate as a percentagetax_amount: Currency - Calculated tax amountis_taxable: bool - Whether this item is taxableactive_till: DateTime - When service expires
Service
Represents an ongoing service provided to a customer.
Properties:
id: u32 - Unique identifiercustomer_id: u32 - ID of the customer receiving the servicetotal_amount: Currency - Total service amount including taxstatus: ServiceStatus - Current service statusbilling_frequency: BillingFrequency - How often the service is billedservice_date: DateTime - When service startedcreated_at: DateTime - Creation timestampupdated_at: DateTime - Last update timestampitems: Vec - List of items in the serviceis_template: bool - Whether this is a template service (to be added)
Methods:
add_item()- Adds an item to the service and updates totalcalculate_total()- Recalculates the total amountupdate_status()- Updates the status of the service
Sale
SaleStatus Enum
Tracks the status of a sale:
Pending- Sale is in progressCompleted- Sale has been finalizedCancelled- Sale has been cancelled
SaleItem
Represents an item within a sale.
Properties:
id: u32 - Unique identifiersale_id: u32 - Parent sale IDproduct_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 saledescription: String - Detailed description of the itemcomments: String - Additional notes or comments about the itemquantity: i32 - Number of items purchasedunit_price: Currency - Price per unitsubtotal: 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 itemactive_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 identifiercompany_id: u32 - ID of the company making the salecustomer_id: u32 - ID of the customer making the purchase (to be added)buyer_name: String - Name of the buyerbuyer_email: String - Email of the buyersubtotal_amount: Currency - Total sale amount before taxtax_amount: Currency - Total tax amount for the saletotal_amount: Currency - Total sale amount including taxstatus: SaleStatus - Current sale statusservice_id: Option - ID of the service created from this sale (to be added)sale_date: DateTime - When sale occurredcreated_at: DateTime - Creation timestampupdated_at: DateTime - Last update timestampitems: Vec - List of items in the sale
Methods:
add_item()- Adds an item to the sale and updates totalsupdate_status()- Updates the status of the salerecalculate_totals()- Recalculates all totals based on itemscreate_service()- Creates a service from this sale (to be added)
Builder:
SaleBuilder- Provides a fluent interface for creating Sale instances
Database Implementation:
- Implements 
Storabletrait for serialization - Implements 
SledModeltrait with:get_id()- Returns the ID as a stringdb_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_productsfor Productinsert_currency,get_currency,delete_currency,list_currenciesfor Currencyinsert_sale,get_sale,delete_sale,list_salesfor Saleinsert_service,get_service,delete_service,list_servicesfor Serviceinsert_invoice,get_invoice,delete_invoice,list_invoicesfor Invoiceinsert_customer,get_customer,delete_customer,list_customersfor Customer
Invoice (Root Object)
InvoiceStatus Enum
Tracks the status of an invoice:
Draft- Invoice is in draft stateSent- Invoice has been sent to the customerPaid- Invoice has been paidOverdue- Invoice is past due dateCancelled- Invoice has been cancelled
PaymentStatus Enum
Tracks the payment status of an invoice:
Unpaid- Invoice has not been paidPartiallyPaid- Invoice has been partially paidPaid- Invoice has been fully paid
Payment
Represents a payment made against an invoice.
Properties:
amount: Currency - Payment amountdate: DateTime - Payment datemethod: String - Payment methodcomment: String - Payment comment
InvoiceItem
Represents an item in an invoice.
Properties:
id: u32 - Unique identifierinvoice_id: u32 - Parent invoice IDdescription: String - Item descriptionamount: Currency - Item amountservice_id: Option - ID of the service this item is forsale_id: Option - ID of the sale this item is for
Methods:
link_to_service()- Links the invoice item to a servicelink_to_sale()- Links the invoice item to a sale
Invoice
Represents an invoice sent to a customer.
Properties:
id: u32 - Unique identifiercustomer_id: u32 - ID of the customer being invoicedtotal_amount: Currency - Total invoice amountbalance_due: Currency - Amount still duestatus: InvoiceStatus - Current invoice statuspayment_status: PaymentStatus - Current payment statusissue_date: DateTime - When invoice was issueddue_date: DateTime - When payment is duecreated_at: DateTime - Creation timestampupdated_at: DateTime - Last update timestampitems: Vec - List of items in the invoicepayments: Vec - List of payments made
Methods:
add_item()- Adds an item to the invoicecalculate_total()- Calculates the total amountadd_payment()- Adds a payment to the invoicecalculate_balance()- Calculates the balance dueupdate_payment_status()- Updates the payment statusupdate_status()- Updates the status of the invoiceis_overdue()- Checks if the invoice is overduecheck_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);