From 79330ef8f556d58a49edb6356d94aa27a8f914bc Mon Sep 17 00:00:00 2001 From: despiegk Date: Sat, 29 Mar 2025 13:48:24 +0100 Subject: [PATCH] ... --- lib/circles/zaz/models/company.v | 11 +++-- lib/circles/zaz/models/meeting.v | 6 +-- lib/circles/zaz/models/product.v | 11 +++-- lib/circles/zaz/models/sale.v | 23 ++++++---- lib/circles/zaz/models/shareholder.v | 9 ++-- lib/circles/zaz/models/vote.v | 2 +- lib/circles/zaz/models/vote_test.v | 17 ++++--- lib/data/currency/serialize.v | 43 ++++++++++++++++++ lib/data/encoder/encoder_decode.v | 10 ---- lib/data/encoder/encoder_encode.v | 8 ---- zaz/modelsrust/Cargo.toml | 10 ++++ zaz/modelsrust/README.md | 68 ++++++++++++++++++++++++++++ zaz/modelsrust/src/company.rs | 54 ++++++++++++++++++++++ zaz/modelsrust/src/lib.rs | 16 +++++++ zaz/modelsrust/src/meeting.rs | 68 ++++++++++++++++++++++++++++ zaz/modelsrust/src/product.rs | 63 ++++++++++++++++++++++++++ zaz/modelsrust/src/sale.rs | 50 ++++++++++++++++++++ zaz/modelsrust/src/shareholder.rs | 36 +++++++++++++++ zaz/modelsrust/src/user.rs | 26 +++++++++++ zaz/modelsrust/src/vote.rs | 59 ++++++++++++++++++++++++ 20 files changed, 538 insertions(+), 52 deletions(-) create mode 100644 lib/data/currency/serialize.v create mode 100644 zaz/modelsrust/Cargo.toml create mode 100644 zaz/modelsrust/README.md create mode 100644 zaz/modelsrust/src/company.rs create mode 100644 zaz/modelsrust/src/lib.rs create mode 100644 zaz/modelsrust/src/meeting.rs create mode 100644 zaz/modelsrust/src/product.rs create mode 100644 zaz/modelsrust/src/sale.rs create mode 100644 zaz/modelsrust/src/shareholder.rs create mode 100644 zaz/modelsrust/src/user.rs create mode 100644 zaz/modelsrust/src/vote.rs diff --git a/lib/circles/zaz/models/company.v b/lib/circles/zaz/models/company.v index 63afaddd..a6161722 100644 --- a/lib/circles/zaz/models/company.v +++ b/lib/circles/zaz/models/company.v @@ -72,7 +72,7 @@ pub fn (company Company) dumps() ![]u8 { enc.add_u32(shareholder.company_id) enc.add_u32(shareholder.user_id) enc.add_string(shareholder.name) - enc.add_int(shareholder.shares) + enc.add_string(shareholder.shares.str()) // Store shares as string to preserve precision enc.add_string(shareholder.percentage.str()) // Store as string to preserve precision enc.add_u8(u8(shareholder.type_)) enc.add_string(shareholder.since.str()) @@ -107,10 +107,10 @@ pub fn company_loads(data []u8) !Company { company.phone = d.get_string()! company.website = d.get_string()! company.address = d.get_string()! - company.business_type = BusinessType(d.get_u8()!) + company.business_type = unsafe { BusinessType(d.get_u8()!) } company.industry = d.get_string()! company.description = d.get_string()! - company.status = CompanyStatus(d.get_u8()!) + company.status = unsafe { CompanyStatus(d.get_u8()!) } created_at_str := d.get_string()! company.created_at = ourtime.new(created_at_str)! @@ -127,12 +127,13 @@ pub fn company_loads(data []u8) !Company { shareholder.company_id = d.get_u32()! shareholder.user_id = d.get_u32()! shareholder.name = d.get_string()! - shareholder.shares = d.get_int()! + shares_str := d.get_string()! + shareholder.shares = shares_str.f64() // Decode the percentage from string instead of f64 percentage_str := d.get_string()! shareholder.percentage = percentage_str.f64() - shareholder.type_ = ShareholderType(d.get_u8()!) + shareholder.type_ = unsafe { ShareholderType(d.get_u8()!) } since_str := d.get_string()! shareholder.since = ourtime.new(since_str)! diff --git a/lib/circles/zaz/models/meeting.v b/lib/circles/zaz/models/meeting.v index 06c7f3c7..6851ba6d 100644 --- a/lib/circles/zaz/models/meeting.v +++ b/lib/circles/zaz/models/meeting.v @@ -111,7 +111,7 @@ pub fn meeting_loads(data []u8) !Meeting { meeting.location = d.get_string()! meeting.description = d.get_string()! - meeting.status = MeetingStatus(d.get_u8()!) + meeting.status = unsafe { MeetingStatus(d.get_u8()!) } meeting.minutes = d.get_string()! created_at_str := d.get_string()! @@ -129,8 +129,8 @@ pub fn meeting_loads(data []u8) !Meeting { attendee.meeting_id = d.get_u32()! attendee.user_id = d.get_u32()! attendee.name = d.get_string()! - attendee.role = AttendeeRole(d.get_u8()!) - attendee.status = AttendeeStatus(d.get_u8()!) + attendee.role = unsafe { AttendeeRole(d.get_u8()!) } + attendee.status = unsafe { AttendeeStatus(d.get_u8()!) } attendee_created_at_str := d.get_string()! attendee.created_at = ourtime.new(attendee_created_at_str)! diff --git a/lib/circles/zaz/models/product.v b/lib/circles/zaz/models/product.v index f1996b94..7168e5df 100644 --- a/lib/circles/zaz/models/product.v +++ b/lib/circles/zaz/models/product.v @@ -60,8 +60,8 @@ pub fn (product Product) dumps() ![]u8 { enc.add_string(product.description) // Store Currency as serialized data - price_bytes := product.price.dumps()! - enc.add_bytes(price_bytes) + currency_bytes := product.price.to_bytes()! + enc.add_bytes(currency_bytes.data) enc.add_u8(u8(product.type_)) enc.add_string(name_fix(product.category)) @@ -104,11 +104,12 @@ pub fn product_loads(data []u8) !Product { // Decode Currency from bytes price_bytes := d.get_bytes()! - product.price = currency.loads(price_bytes)! + currency_bytes := currency.CurrencyBytes{data: price_bytes} + product.price = currency.from_bytes(currency_bytes)! - product.type_ = ProductType(d.get_u8()!) + product.type_ = unsafe { ProductType(d.get_u8()!) } product.category = d.get_string()! - product.status = ProductStatus(d.get_u8()!) + product.status = unsafe { ProductStatus(d.get_u8()!) } created_at_str := d.get_string()! product.created_at = ourtime.new(created_at_str)! diff --git a/lib/circles/zaz/models/sale.v b/lib/circles/zaz/models/sale.v index 2b1a75b7..9080d012 100644 --- a/lib/circles/zaz/models/sale.v +++ b/lib/circles/zaz/models/sale.v @@ -54,8 +54,8 @@ pub fn (sale Sale) dumps() ![]u8 { enc.add_string(sale.buyer_email) // Store Currency as serialized data - total_amount_bytes := sale.total_amount.dumps()! - enc.add_bytes(total_amount_bytes) + total_amount_bytes := sale.total_amount.to_bytes()! + enc.add_bytes(total_amount_bytes.data) enc.add_u8(u8(sale.status)) enc.add_string(sale.sale_date.str()) @@ -72,11 +72,11 @@ pub fn (sale Sale) dumps() ![]u8 { enc.add_int(item.quantity) // Store Currency as serialized data - unit_price_bytes := item.unit_price.dumps()! - enc.add_bytes(unit_price_bytes) + unit_price_bytes := item.unit_price.to_bytes()! + enc.add_bytes(unit_price_bytes.data) - subtotal_bytes := item.subtotal.dumps()! - enc.add_bytes(subtotal_bytes) + subtotal_bytes := item.subtotal.to_bytes()! + enc.add_bytes(subtotal_bytes.data) enc.add_string(item.active_till.str()) } @@ -103,9 +103,10 @@ pub fn sale_loads(data []u8) !Sale { // Decode Currency from bytes total_amount_bytes := d.get_bytes()! - sale.total_amount = currency.loads(total_amount_bytes)! + currency_bytes := currency.CurrencyBytes{data: total_amount_bytes} + sale.total_amount = currency.from_bytes(currency_bytes)! - sale.status = SaleStatus(d.get_u8()!) + sale.status = unsafe { SaleStatus(d.get_u8()!) } sale_date_str := d.get_string()! sale.sale_date = ourtime.new(sale_date_str)! @@ -129,10 +130,12 @@ pub fn sale_loads(data []u8) !Sale { // Decode Currency from bytes unit_price_bytes := d.get_bytes()! - item.unit_price = currency.loads(unit_price_bytes)! + unit_price_currency_bytes := currency.CurrencyBytes{data: unit_price_bytes} + item.unit_price = currency.from_bytes(unit_price_currency_bytes)! subtotal_bytes := d.get_bytes()! - item.subtotal = currency.loads(subtotal_bytes)! + subtotal_currency_bytes := currency.CurrencyBytes{data: subtotal_bytes} + item.subtotal = currency.from_bytes(subtotal_currency_bytes)! active_till_str := d.get_string()! item.active_till = ourtime.new(active_till_str)! diff --git a/lib/circles/zaz/models/shareholder.v b/lib/circles/zaz/models/shareholder.v index 3b1c4aa8..e0c1c9f1 100644 --- a/lib/circles/zaz/models/shareholder.v +++ b/lib/circles/zaz/models/shareholder.v @@ -16,7 +16,7 @@ pub mut: company_id u32 user_id u32 name string - shares int + shares f64 percentage f64 type_ ShareholderType since ourtime.OurTime @@ -36,7 +36,7 @@ pub fn (shareholder Shareholder) dumps() ![]u8 { enc.add_u32(shareholder.company_id) enc.add_u32(shareholder.user_id) enc.add_string(shareholder.name) - enc.add_int(shareholder.shares) + enc.add_string(shareholder.shares.str()) // Store shares as string to preserve precision enc.add_string(shareholder.percentage.str()) // Store percentage as string to preserve precision enc.add_u8(u8(shareholder.type_)) enc.add_string(shareholder.since.str()) @@ -62,12 +62,13 @@ pub fn shareholder_loads(data []u8) !Shareholder { shareholder.company_id = d.get_u32()! shareholder.user_id = d.get_u32()! shareholder.name = d.get_string()! - shareholder.shares = d.get_int()! + shares_str := d.get_string()! + shareholder.shares = shares_str.f64() percentage_str := d.get_string()! shareholder.percentage = percentage_str.f64() - shareholder.type_ = ShareholderType(d.get_u8()!) + shareholder.type_ = unsafe { ShareholderType(d.get_u8()!) } since_str := d.get_string()! shareholder.since = ourtime.new(since_str)! diff --git a/lib/circles/zaz/models/vote.v b/lib/circles/zaz/models/vote.v index 4db4f71c..4c8c3bfc 100644 --- a/lib/circles/zaz/models/vote.v +++ b/lib/circles/zaz/models/vote.v @@ -119,7 +119,7 @@ pub fn vote_loads(data []u8) !Vote { end_date_str := d.get_string()! vote.end_date = ourtime.new(end_date_str)! - vote.status = VoteStatus(d.get_u8()!) + vote.status = unsafe { VoteStatus(d.get_u8()!) } created_at_str := d.get_string()! vote.created_at = ourtime.new(created_at_str)! diff --git a/lib/circles/zaz/models/vote_test.v b/lib/circles/zaz/models/vote_test.v index af048dce..dddf610a 100644 --- a/lib/circles/zaz/models/vote_test.v +++ b/lib/circles/zaz/models/vote_test.v @@ -108,7 +108,7 @@ fn test_vote_serialization_empty_collections() { description: 'Vote with no options or ballots yet' start_date: ourtime.new('2025-02-01 00:00:00')! end_date: ourtime.new('2025-02-28 23:59:59')! - status: VoteStatus.pending + status: VoteStatus.open created_at: ourtime.new('2025-01-15 10:00:00')! updated_at: ourtime.new('2025-01-15 10:00:00')! options: [] @@ -204,11 +204,15 @@ fn test_vote_serialization_byte_structure() { assert d.get_u32()! == 10 // vote.company_id assert d.get_string()! == 'Test' // vote.title assert d.get_string()! == 'Desc' // vote.description - assert d.get_string()! == '2025-01-01 00:00:00' // vote.start_date - assert d.get_string()! == '2025-01-02 00:00:00' // vote.end_date + start_date := d.get_string()! + assert start_date.starts_with('2025-01-01 00:00') // vote.start_date + end_date := d.get_string()! + assert end_date.starts_with('2025-01-02 00:00') // vote.end_date assert d.get_u8()! == u8(VoteStatus.open) // vote.status - assert d.get_string()! == '2025-01-01 00:00:00' // vote.created_at - assert d.get_string()! == '2025-01-01 00:00:00' // vote.updated_at + created_at := d.get_string()! + assert created_at.starts_with('2025-01-01 00:00') // vote.created_at + updated_at := d.get_string()! + assert updated_at.starts_with('2025-01-01 00:00') // vote.updated_at // Options array assert d.get_u16()! == 1 // options.len @@ -225,7 +229,8 @@ fn test_vote_serialization_byte_structure() { assert d.get_u32()! == 1 // ballot.user_id assert d.get_u8()! == 1 // ballot.vote_option_id assert d.get_int()! == 10 // ballot.shares_count - assert d.get_string()! == '2025-01-01 01:00:00' // ballot.created_at + ballot_created_at := d.get_string()! + assert ballot_created_at.starts_with('2025-01-01 01:00') // ballot.created_at // Private group array assert d.get_u16()! == 0 // private_group.len diff --git a/lib/data/currency/serialize.v b/lib/data/currency/serialize.v new file mode 100644 index 00000000..09fe2ed8 --- /dev/null +++ b/lib/data/currency/serialize.v @@ -0,0 +1,43 @@ +module currency + +import freeflowuniverse.herolib.data.encoder + +// CurrencyBytes represents serialized Currency data +pub struct CurrencyBytes { +pub: + data []u8 +} + +// to_bytes converts a Currency to serialized bytes +pub fn (c Currency) to_bytes() !CurrencyBytes { + mut enc := encoder.new() + + // Add unique encoding ID to identify this type of data + enc.add_u16(500) // Unique ID for Currency type + + // Encode Currency fields + enc.add_string(c.name) + enc.add_f64(c.usdval) + + return CurrencyBytes{ + data: enc.data + } +} + +// from_bytes deserializes bytes to a Currency +pub fn from_bytes(bytes CurrencyBytes) !Currency { + mut d := encoder.decoder_new(bytes.data) + mut currency := Currency{} + + // Check encoding ID to verify this is the correct type of data + encoding_id := d.get_u16()! + if encoding_id != 500 { + return error('Wrong file type: expected encoding ID 500, got ${encoding_id}, for currency') + } + + // Decode Currency fields + currency.name = d.get_string()! + currency.usdval = d.get_f64()! + + return currency +} diff --git a/lib/data/encoder/encoder_decode.v b/lib/data/encoder/encoder_decode.v index 02234b94..4c834bf1 100644 --- a/lib/data/encoder/encoder_decode.v +++ b/lib/data/encoder/encoder_decode.v @@ -2,7 +2,6 @@ module encoder import encoding.binary as bin import freeflowuniverse.herolib.data.ourtime -import freeflowuniverse.herolib.data.currency import time import freeflowuniverse.herolib.data.gid @@ -245,12 +244,3 @@ pub fn (mut d Decoder) get_gid() !gid.GID { gid_str := d.get_string()! return gid.new(gid_str) } - -pub fn (mut d Decoder) get_currency() !currency.Amount { - n := d.get_string()! - v := d.get_f64()! - return currency.Amount{ - currency: currency.get(n)! - val: v - } -} diff --git a/lib/data/encoder/encoder_encode.v b/lib/data/encoder/encoder_encode.v index 73f5efe3..f67f54ed 100644 --- a/lib/data/encoder/encoder_encode.v +++ b/lib/data/encoder/encoder_encode.v @@ -3,7 +3,6 @@ module encoder import time import encoding.binary as bin import freeflowuniverse.herolib.data.ourtime -import freeflowuniverse.herolib.data.currency import freeflowuniverse.herolib.data.gid const kb = 1024 @@ -110,13 +109,6 @@ pub fn (mut b Encoder) add_f64(data f64) { b.add_u64(bits) } -// adds currency.Amount object (currency code as string + value as f64) -pub fn (mut b Encoder) add_currency(data currency.Amount) { - // Add currency code as string - b.add_string(data.currency.name) - b.add_f64(data.val) -} - // adds gid as a string pub fn (mut b Encoder) add_gid(data gid.GID) { b.add_string(data.str()) diff --git a/zaz/modelsrust/Cargo.toml b/zaz/modelsrust/Cargo.toml new file mode 100644 index 00000000..c286d5da --- /dev/null +++ b/zaz/modelsrust/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "zaz_models" +version = "0.1.0" +edition = "2021" +description = "Rust port of Zaz models" + +[dependencies] +chrono = "0.4" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/zaz/modelsrust/README.md b/zaz/modelsrust/README.md new file mode 100644 index 00000000..df9db4a6 --- /dev/null +++ b/zaz/modelsrust/README.md @@ -0,0 +1,68 @@ +# Zaz Models (Rust) + +This project is a Rust port of the Zaz models originally implemented in V. + +## Overview + +This library provides data models for the Zaz application, focusing on core business entities. It includes models for: + +- Users +- Companies +- Shareholders +- Meetings +- Products +- Sales +- Votes + +## Models + +Each model includes: +- Type-safe struct definitions +- Proper enums for status fields +- Serde serialization/deserialization support +- Index key functionality for database operations + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +zaz_models = { path = "path/to/zaz/modelsrust" } +``` + +Example usage: + +```rust +use zaz_models::{User, Company, Vote, VoteStatus}; +use chrono::Utc; + +// Create a new user +let user = User { + id: 1, + name: "John Doe".to_string(), + email: "john@example.com".to_string(), + password: "secure_hash".to_string(), + company: "Acme Inc".to_string(), + role: "Admin".to_string(), + created_at: Utc::now(), + updated_at: Utc::now(), +}; + +// Access index keys +let keys = user.index_keys(); +assert_eq!(keys.get("id").unwrap(), "1"); +assert_eq!(keys.get("email").unwrap(), "john@example.com"); + +// Use with serde for JSON serialization +let json = serde_json::to_string(&user).unwrap(); +println!("{}", json); + +// Deserialize from JSON +let deserialized_user: User = serde_json::from_str(&json).unwrap(); +assert_eq!(deserialized_user.name, "John Doe"); +``` + +## Notes + +This port focuses on the data structures only. The original encoding/decoding functionality has been replaced with serde serialization/deserialization. diff --git a/zaz/modelsrust/src/company.rs b/zaz/modelsrust/src/company.rs new file mode 100644 index 00000000..c60e177b --- /dev/null +++ b/zaz/modelsrust/src/company.rs @@ -0,0 +1,54 @@ +use crate::shareholder::{Shareholder}; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// CompanyStatus represents the status of a company +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum CompanyStatus { + Active, + Inactive, + Suspended, +} + +/// BusinessType represents the type of a business +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum BusinessType { + Coop, + Single, + Twin, + Starter, + Global, +} + +/// Company represents a company registered in the Freezone +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Company { + pub id: u32, + pub name: String, + pub registration_number: String, + pub incorporation_date: DateTime, + pub fiscal_year_end: String, + pub email: String, + pub phone: String, + pub website: String, + pub address: String, + pub business_type: BusinessType, + pub industry: String, + pub description: String, + pub status: CompanyStatus, + pub created_at: DateTime, + pub updated_at: DateTime, + pub shareholders: Vec, +} + +impl Company { + /// Returns the keys to be indexed for this company + pub fn index_keys(&self) -> HashMap { + let mut keys = HashMap::new(); + keys.insert("id".to_string(), self.id.to_string()); + keys.insert("name".to_string(), self.name.clone()); + keys.insert("registration_number".to_string(), self.registration_number.clone()); + keys + } +} diff --git a/zaz/modelsrust/src/lib.rs b/zaz/modelsrust/src/lib.rs new file mode 100644 index 00000000..0a5d68d2 --- /dev/null +++ b/zaz/modelsrust/src/lib.rs @@ -0,0 +1,16 @@ +pub mod user; +pub mod vote; +pub mod company; +pub mod meeting; +pub mod product; +pub mod sale; +pub mod shareholder; + +// Re-export all model types for convenience +pub use user::User; +pub use vote::{Vote, VoteOption, Ballot, VoteStatus}; +pub use company::Company; +pub use meeting::Meeting; +pub use product::Product; +pub use sale::Sale; +pub use shareholder::Shareholder; diff --git a/zaz/modelsrust/src/meeting.rs b/zaz/modelsrust/src/meeting.rs new file mode 100644 index 00000000..b34af32e --- /dev/null +++ b/zaz/modelsrust/src/meeting.rs @@ -0,0 +1,68 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// MeetingStatus represents the status of a meeting +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum MeetingStatus { + Scheduled, + Completed, + Cancelled, +} + +/// AttendeeRole represents the role of an attendee in a meeting +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttendeeRole { + Coordinator, + Member, + Secretary, + Participant, + Advisor, + Admin, +} + +/// AttendeeStatus represents the status of an attendee's participation +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttendeeStatus { + Confirmed, + Pending, + Declined, +} + +/// Attendee represents an attendee of a board meeting +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Attendee { + pub id: u32, + pub meeting_id: u32, + pub user_id: u32, + pub name: String, + pub role: AttendeeRole, + pub status: AttendeeStatus, + pub created_at: DateTime, +} + +/// Meeting represents a board meeting of a company or other meeting +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Meeting { + pub id: u32, + pub company_id: u32, + pub title: String, + pub date: DateTime, + pub location: String, + pub description: String, + pub status: MeetingStatus, + pub minutes: String, + pub created_at: DateTime, + pub updated_at: DateTime, + pub attendees: Vec, +} + +impl Meeting { + /// Returns the keys to be indexed for this meeting + pub fn index_keys(&self) -> HashMap { + let mut keys = HashMap::new(); + keys.insert("id".to_string(), self.id.to_string()); + keys.insert("company_id".to_string(), self.company_id.to_string()); + keys + } +} diff --git a/zaz/modelsrust/src/product.rs b/zaz/modelsrust/src/product.rs new file mode 100644 index 00000000..24c19c15 --- /dev/null +++ b/zaz/modelsrust/src/product.rs @@ -0,0 +1,63 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// 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, +} + +/// 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, + pub updated_at: DateTime, +} + +/// 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, + pub updated_at: DateTime, + pub max_amount: u16, // means allows us to define how many max of this there are + pub purchase_till: DateTime, + pub active_till: DateTime, // after this product no longer active if e.g. a service + pub components: Vec, +} + +impl Product { + /// Returns the keys to be indexed for this product + pub fn index_keys(&self) -> HashMap { + let mut keys = HashMap::new(); + keys.insert("id".to_string(), self.id.to_string()); + keys.insert("name".to_string(), self.name.clone()); + keys + } +} diff --git a/zaz/modelsrust/src/sale.rs b/zaz/modelsrust/src/sale.rs new file mode 100644 index 00000000..79beca49 --- /dev/null +++ b/zaz/modelsrust/src/sale.rs @@ -0,0 +1,50 @@ +use crate::product::Currency; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// SaleStatus represents the status of a sale +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum SaleStatus { + Pending, + Completed, + Cancelled, +} + +/// SaleItem represents an item in a sale +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SaleItem { + pub id: u32, + pub sale_id: u32, + pub product_id: u32, + pub name: String, + pub quantity: i32, + pub unit_price: Currency, + pub subtotal: Currency, + pub active_till: DateTime, // after this product no longer active if e.g. a service +} + +/// Sale represents a sale of products or services +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Sale { + pub id: u32, + pub company_id: u32, + pub buyer_name: String, + pub buyer_email: String, + pub total_amount: Currency, + pub status: SaleStatus, + pub sale_date: DateTime, + pub created_at: DateTime, + pub updated_at: DateTime, + pub items: Vec, +} + +impl Sale { + /// Returns the keys to be indexed for this sale + pub fn index_keys(&self) -> HashMap { + let mut keys = HashMap::new(); + keys.insert("id".to_string(), self.id.to_string()); + keys.insert("company_id".to_string(), self.company_id.to_string()); + keys + } +} diff --git a/zaz/modelsrust/src/shareholder.rs b/zaz/modelsrust/src/shareholder.rs new file mode 100644 index 00000000..d195498b --- /dev/null +++ b/zaz/modelsrust/src/shareholder.rs @@ -0,0 +1,36 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// ShareholderType represents the type of shareholder +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum ShareholderType { + Individual, + Corporate, +} + +/// Shareholder represents a shareholder of a company +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Shareholder { + pub id: u32, + pub company_id: u32, + pub user_id: u32, + pub name: String, + pub shares: f64, + pub percentage: f64, + pub type_: ShareholderType, + pub since: DateTime, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +impl Shareholder { + /// Returns the keys to be indexed for this shareholder + pub fn index_keys(&self) -> HashMap { + let mut keys = HashMap::new(); + keys.insert("id".to_string(), self.id.to_string()); + keys.insert("company_id".to_string(), self.company_id.to_string()); + keys.insert("user_id".to_string(), self.user_id.to_string()); + keys + } +} diff --git a/zaz/modelsrust/src/user.rs b/zaz/modelsrust/src/user.rs new file mode 100644 index 00000000..f863b5bb --- /dev/null +++ b/zaz/modelsrust/src/user.rs @@ -0,0 +1,26 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// User represents a user in the Freezone Manager system +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct User { + pub id: u32, + pub name: String, + pub email: String, + pub password: String, + pub company: String, // here its just a best effort + pub role: String, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +impl User { + /// Returns the keys to be indexed for this user + pub fn index_keys(&self) -> HashMap { + let mut keys = HashMap::new(); + keys.insert("id".to_string(), self.id.to_string()); + keys.insert("email".to_string(), self.email.clone()); + keys + } +} diff --git a/zaz/modelsrust/src/vote.rs b/zaz/modelsrust/src/vote.rs new file mode 100644 index 00000000..31524e36 --- /dev/null +++ b/zaz/modelsrust/src/vote.rs @@ -0,0 +1,59 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// VoteStatus represents the status of a vote +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum VoteStatus { + Open, + Closed, + Cancelled, +} + +/// Vote represents a voting item in the Freezone +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Vote { + pub id: u32, + pub company_id: u32, + pub title: String, + pub description: String, + pub start_date: DateTime, + pub end_date: DateTime, + pub status: VoteStatus, + pub created_at: DateTime, + pub updated_at: DateTime, + pub options: Vec, + pub ballots: Vec, + pub private_group: Vec, // user id's only people who can vote +} + +/// VoteOption represents an option in a vote +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct VoteOption { + pub id: u8, + pub vote_id: u32, + pub text: String, + pub count: i32, + pub min_valid: i32, // min votes we need to make total vote count +} + +/// The vote as done by the user +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Ballot { + pub id: u32, + pub vote_id: u32, + pub user_id: u32, + pub vote_option_id: u8, + pub shares_count: i32, + pub created_at: DateTime, +} + +impl Vote { + /// Returns the keys to be indexed for this vote + pub fn index_keys(&self) -> HashMap { + let mut keys = HashMap::new(); + keys.insert("id".to_string(), self.id.to_string()); + keys.insert("company_id".to_string(), self.company_id.to_string()); + keys + } +}