rwda ui implementation
This commit is contained in:
282
actix_mvc_app/src/models/asset.rs
Normal file
282
actix_mvc_app/src/models/asset.rs
Normal file
@@ -0,0 +1,282 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Asset types representing different categories of digital assets
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub enum AssetType {
|
||||
NFT,
|
||||
Token,
|
||||
RealEstate,
|
||||
Commodity,
|
||||
Share,
|
||||
Bond,
|
||||
IntellectualProperty,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl AssetType {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
AssetType::NFT => "NFT",
|
||||
AssetType::Token => "Token",
|
||||
AssetType::RealEstate => "Real Estate",
|
||||
AssetType::Commodity => "Commodity",
|
||||
AssetType::Share => "Share",
|
||||
AssetType::Bond => "Bond",
|
||||
AssetType::IntellectualProperty => "Intellectual Property",
|
||||
AssetType::Other => "Other",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Status of an asset
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub enum AssetStatus {
|
||||
Active,
|
||||
Locked,
|
||||
ForSale,
|
||||
Transferred,
|
||||
Archived,
|
||||
}
|
||||
|
||||
impl AssetStatus {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
AssetStatus::Active => "Active",
|
||||
AssetStatus::Locked => "Locked",
|
||||
AssetStatus::ForSale => "For Sale",
|
||||
AssetStatus::Transferred => "Transferred",
|
||||
AssetStatus::Archived => "Archived",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Blockchain information for an asset
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BlockchainInfo {
|
||||
pub blockchain: String,
|
||||
pub token_id: String,
|
||||
pub contract_address: String,
|
||||
pub owner_address: String,
|
||||
pub transaction_hash: Option<String>,
|
||||
pub block_number: Option<u64>,
|
||||
pub timestamp: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
/// Valuation history point for an asset
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ValuationPoint {
|
||||
pub id: String,
|
||||
pub date: DateTime<Utc>,
|
||||
pub value: f64,
|
||||
pub currency: String,
|
||||
pub source: String,
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
/// Transaction history for an asset
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AssetTransaction {
|
||||
pub id: String,
|
||||
pub transaction_type: String,
|
||||
pub date: DateTime<Utc>,
|
||||
pub from_address: Option<String>,
|
||||
pub to_address: Option<String>,
|
||||
pub amount: Option<f64>,
|
||||
pub currency: Option<String>,
|
||||
pub transaction_hash: Option<String>,
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
/// Main Asset model
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Asset {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub asset_type: AssetType,
|
||||
pub status: AssetStatus,
|
||||
pub owner_id: String,
|
||||
pub owner_name: String,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub blockchain_info: Option<BlockchainInfo>,
|
||||
pub current_valuation: Option<f64>,
|
||||
pub valuation_currency: Option<String>,
|
||||
pub valuation_date: Option<DateTime<Utc>>,
|
||||
pub valuation_history: Vec<ValuationPoint>,
|
||||
pub transaction_history: Vec<AssetTransaction>,
|
||||
pub metadata: serde_json::Value,
|
||||
pub image_url: Option<String>,
|
||||
pub external_url: Option<String>,
|
||||
}
|
||||
|
||||
impl Asset {
|
||||
/// Creates a new asset
|
||||
pub fn new(
|
||||
name: &str,
|
||||
description: &str,
|
||||
asset_type: AssetType,
|
||||
owner_id: &str,
|
||||
owner_name: &str,
|
||||
) -> Self {
|
||||
let now = Utc::now();
|
||||
Self {
|
||||
id: format!("asset-{}", Uuid::new_v4().to_string()[..8].to_string()),
|
||||
name: name.to_string(),
|
||||
description: description.to_string(),
|
||||
asset_type,
|
||||
status: AssetStatus::Active,
|
||||
owner_id: owner_id.to_string(),
|
||||
owner_name: owner_name.to_string(),
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
blockchain_info: None,
|
||||
current_valuation: None,
|
||||
valuation_currency: None,
|
||||
valuation_date: None,
|
||||
valuation_history: Vec::new(),
|
||||
transaction_history: Vec::new(),
|
||||
metadata: serde_json::json!({}),
|
||||
image_url: None,
|
||||
external_url: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds blockchain information to the asset
|
||||
pub fn add_blockchain_info(&mut self, blockchain_info: BlockchainInfo) {
|
||||
self.blockchain_info = Some(blockchain_info);
|
||||
self.updated_at = Utc::now();
|
||||
}
|
||||
|
||||
/// Adds a valuation point to the asset's history
|
||||
pub fn add_valuation(&mut self, value: f64, currency: &str, source: &str, notes: Option<String>) {
|
||||
let valuation = ValuationPoint {
|
||||
id: format!("val-{}", Uuid::new_v4().to_string()[..8].to_string()),
|
||||
date: Utc::now(),
|
||||
value,
|
||||
currency: currency.to_string(),
|
||||
source: source.to_string(),
|
||||
notes,
|
||||
};
|
||||
|
||||
self.current_valuation = Some(value);
|
||||
self.valuation_currency = Some(currency.to_string());
|
||||
self.valuation_date = Some(valuation.date);
|
||||
self.valuation_history.push(valuation);
|
||||
self.updated_at = Utc::now();
|
||||
}
|
||||
|
||||
/// Adds a transaction to the asset's history
|
||||
pub fn add_transaction(
|
||||
&mut self,
|
||||
transaction_type: &str,
|
||||
from_address: Option<String>,
|
||||
to_address: Option<String>,
|
||||
amount: Option<f64>,
|
||||
currency: Option<String>,
|
||||
transaction_hash: Option<String>,
|
||||
notes: Option<String>,
|
||||
) {
|
||||
let transaction = AssetTransaction {
|
||||
id: format!("tx-{}", Uuid::new_v4().to_string()[..8].to_string()),
|
||||
transaction_type: transaction_type.to_string(),
|
||||
date: Utc::now(),
|
||||
from_address,
|
||||
to_address,
|
||||
amount,
|
||||
currency,
|
||||
transaction_hash,
|
||||
notes,
|
||||
};
|
||||
|
||||
self.transaction_history.push(transaction);
|
||||
self.updated_at = Utc::now();
|
||||
}
|
||||
|
||||
/// Updates the status of the asset
|
||||
pub fn update_status(&mut self, status: AssetStatus) {
|
||||
self.status = status;
|
||||
self.updated_at = Utc::now();
|
||||
}
|
||||
|
||||
/// Gets the latest valuation point
|
||||
pub fn latest_valuation(&self) -> Option<&ValuationPoint> {
|
||||
self.valuation_history.last()
|
||||
}
|
||||
|
||||
/// Gets the latest transaction
|
||||
pub fn latest_transaction(&self) -> Option<&AssetTransaction> {
|
||||
self.transaction_history.last()
|
||||
}
|
||||
|
||||
/// Gets the valuation history sorted by date
|
||||
pub fn sorted_valuation_history(&self) -> Vec<&ValuationPoint> {
|
||||
let mut history = self.valuation_history.iter().collect::<Vec<_>>();
|
||||
history.sort_by(|a, b| a.date.cmp(&b.date));
|
||||
history
|
||||
}
|
||||
|
||||
/// Gets the transaction history sorted by date
|
||||
pub fn sorted_transaction_history(&self) -> Vec<&AssetTransaction> {
|
||||
let mut history = self.transaction_history.iter().collect::<Vec<_>>();
|
||||
history.sort_by(|a, b| a.date.cmp(&b.date));
|
||||
history
|
||||
}
|
||||
}
|
||||
|
||||
/// Filter for assets
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AssetFilter {
|
||||
pub asset_type: Option<AssetType>,
|
||||
pub status: Option<AssetStatus>,
|
||||
pub owner_id: Option<String>,
|
||||
pub min_valuation: Option<f64>,
|
||||
pub max_valuation: Option<f64>,
|
||||
pub valuation_currency: Option<String>,
|
||||
pub search_query: Option<String>,
|
||||
}
|
||||
|
||||
/// Statistics for assets
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AssetStatistics {
|
||||
pub total_assets: usize,
|
||||
pub total_value: f64,
|
||||
pub value_by_type: std::collections::HashMap<String, f64>,
|
||||
pub assets_by_type: std::collections::HashMap<String, usize>,
|
||||
pub assets_by_status: std::collections::HashMap<String, usize>,
|
||||
}
|
||||
|
||||
impl AssetStatistics {
|
||||
pub fn new(assets: &[Asset]) -> Self {
|
||||
let mut total_value = 0.0;
|
||||
let mut value_by_type = std::collections::HashMap::new();
|
||||
let mut assets_by_type = std::collections::HashMap::new();
|
||||
let mut assets_by_status = std::collections::HashMap::new();
|
||||
|
||||
for asset in assets {
|
||||
if let Some(valuation) = asset.current_valuation {
|
||||
total_value += valuation;
|
||||
|
||||
let asset_type = asset.asset_type.as_str().to_string();
|
||||
*value_by_type.entry(asset_type.clone()).or_insert(0.0) += valuation;
|
||||
*assets_by_type.entry(asset_type).or_insert(0) += 1;
|
||||
} else {
|
||||
let asset_type = asset.asset_type.as_str().to_string();
|
||||
*assets_by_type.entry(asset_type).or_insert(0) += 1;
|
||||
}
|
||||
|
||||
let status = asset.status.as_str().to_string();
|
||||
*assets_by_status.entry(status).or_insert(0) += 1;
|
||||
}
|
||||
|
||||
Self {
|
||||
total_assets: assets.len(),
|
||||
total_value,
|
||||
value_by_type,
|
||||
assets_by_type,
|
||||
assets_by_status,
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,6 +5,7 @@ pub mod calendar;
|
||||
pub mod governance;
|
||||
pub mod flow;
|
||||
pub mod contract;
|
||||
pub mod asset;
|
||||
|
||||
// Re-export models for easier imports
|
||||
pub use user::User;
|
||||
|
Reference in New Issue
Block a user