156 lines
4.3 KiB
Rust
156 lines
4.3 KiB
Rust
use chrono::{DateTime, Utc, Duration};
|
|
use serde::{Deserialize, Serialize};
|
|
use crate::db::core::{SledModel, Storable}; // Import Sled traits from new location
|
|
|
|
/// Currency represents a monetary value with amount and currency code
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Currency {
|
|
pub amount: f64,
|
|
pub currency_code: String,
|
|
}
|
|
|
|
impl Currency {
|
|
/// Create a new currency with amount and code
|
|
pub fn new(amount: f64, currency_code: String) -> Self {
|
|
Self {
|
|
amount,
|
|
currency_code,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// ProductType represents the type of a product
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum ProductType {
|
|
Product,
|
|
Service,
|
|
}
|
|
|
|
/// ProductStatus represents the status of a product
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum ProductStatus {
|
|
Available,
|
|
Unavailable,
|
|
}
|
|
|
|
/// ProductComponent represents a component of a product
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ProductComponent {
|
|
pub id: u32,
|
|
pub name: String,
|
|
pub description: String,
|
|
pub quantity: i32,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
impl ProductComponent {
|
|
/// Create a new product component with default timestamps
|
|
pub fn new(id: u32, name: String, description: String, quantity: i32) -> Self {
|
|
let now = Utc::now();
|
|
Self {
|
|
id,
|
|
name,
|
|
description,
|
|
quantity,
|
|
created_at: now,
|
|
updated_at: now,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Product represents a product or service offered by the Freezone
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Product {
|
|
pub id: u32,
|
|
pub name: String,
|
|
pub description: String,
|
|
pub price: Currency,
|
|
pub type_: ProductType,
|
|
pub category: String,
|
|
pub status: ProductStatus,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
pub max_amount: u16, // means allows us to define how many max of this there are
|
|
pub purchase_till: DateTime<Utc>,
|
|
pub active_till: DateTime<Utc>, // after this product no longer active if e.g. a service
|
|
pub components: Vec<ProductComponent>,
|
|
}
|
|
|
|
// Removed old Model trait implementation
|
|
|
|
impl Product {
|
|
/// Create a new product with default timestamps
|
|
pub fn new(
|
|
id: u32,
|
|
name: String,
|
|
description: String,
|
|
price: Currency,
|
|
type_: ProductType,
|
|
category: String,
|
|
status: ProductStatus,
|
|
max_amount: u16,
|
|
validity_days: i64, // How many days the product is valid after purchase
|
|
) -> Self {
|
|
let now = Utc::now();
|
|
// Default: purchasable for 1 year, active for specified validity days after purchase
|
|
Self {
|
|
id,
|
|
name,
|
|
description,
|
|
price,
|
|
type_,
|
|
category,
|
|
status,
|
|
created_at: now,
|
|
updated_at: now,
|
|
max_amount,
|
|
purchase_till: now + Duration::days(365),
|
|
active_till: now + Duration::days(validity_days),
|
|
components: Vec::new(),
|
|
}
|
|
}
|
|
|
|
/// Add a component to this product
|
|
pub fn add_component(&mut self, component: ProductComponent) {
|
|
self.components.push(component);
|
|
self.updated_at = Utc::now();
|
|
}
|
|
|
|
/// Update the purchase availability timeframe
|
|
pub fn set_purchase_period(&mut self, purchase_till: DateTime<Utc>) {
|
|
self.purchase_till = purchase_till;
|
|
self.updated_at = Utc::now();
|
|
}
|
|
|
|
/// Update the active timeframe
|
|
pub fn set_active_period(&mut self, active_till: DateTime<Utc>) {
|
|
self.active_till = active_till;
|
|
self.updated_at = Utc::now();
|
|
}
|
|
|
|
/// Check if the product is available for purchase
|
|
pub fn is_purchasable(&self) -> bool {
|
|
self.status == ProductStatus::Available && Utc::now() <= self.purchase_till
|
|
}
|
|
|
|
/// Check if the product is still active (for services)
|
|
pub fn is_active(&self) -> bool {
|
|
Utc::now() <= self.active_till
|
|
}
|
|
}
|
|
|
|
// Implement Storable trait (provides default dump/load)
|
|
impl Storable for Product {}
|
|
|
|
// Implement SledModel trait
|
|
impl SledModel for Product {
|
|
fn get_id(&self) -> String {
|
|
self.id.to_string()
|
|
}
|
|
|
|
fn db_prefix() -> &'static str {
|
|
"product"
|
|
}
|
|
}
|