feat: Load voting
This commit is contained in:
parent
5d9eaac1f8
commit
916f435dbc
@ -130,8 +130,8 @@ impl GovernanceController {
|
|||||||
if let Ok(Some(proposal)) = proposal {
|
if let Ok(Some(proposal)) = proposal {
|
||||||
ctx.insert("proposal", &proposal);
|
ctx.insert("proposal", &proposal);
|
||||||
|
|
||||||
// Get mock votes for this proposal
|
// Extract votes directly from the proposal
|
||||||
let votes = Self::get_mock_votes_for_proposal(&proposal_id);
|
let votes = Self::extract_votes_from_proposal(&proposal);
|
||||||
ctx.insert("votes", &votes);
|
ctx.insert("votes", &votes);
|
||||||
|
|
||||||
// Calculate voting results directly from the proposal
|
// Calculate voting results directly from the proposal
|
||||||
@ -301,14 +301,14 @@ impl GovernanceController {
|
|||||||
user_id,
|
user_id,
|
||||||
&form.vote_type,
|
&form.vote_type,
|
||||||
1, // Default to 1 share
|
1, // Default to 1 share
|
||||||
|
form.comment.as_ref().map(|s| s.to_string()), // Pass the comment from the form
|
||||||
) {
|
) {
|
||||||
Ok(updated_proposal) => {
|
Ok(updated_proposal) => {
|
||||||
ctx.insert("proposal", &updated_proposal);
|
ctx.insert("proposal", &updated_proposal);
|
||||||
ctx.insert("success", "Your vote has been recorded!");
|
ctx.insert("success", "Your vote has been recorded!");
|
||||||
|
|
||||||
// Get votes for this proposal
|
// Extract votes directly from the updated proposal
|
||||||
// For now, we'll still use mock votes until we implement a function to extract votes from the proposal
|
let votes = Self::extract_votes_from_proposal(&updated_proposal);
|
||||||
let votes = Self::get_mock_votes_for_proposal(&proposal_id);
|
|
||||||
ctx.insert("votes", &votes);
|
ctx.insert("votes", &votes);
|
||||||
|
|
||||||
// Calculate voting results directly from the updated proposal
|
// Calculate voting results directly from the updated proposal
|
||||||
@ -639,6 +639,95 @@ impl GovernanceController {
|
|||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract votes from a proposal's ballots
|
||||||
|
fn extract_votes_from_proposal(proposal: &Proposal) -> Vec<Vote> {
|
||||||
|
let mut votes = Vec::new();
|
||||||
|
|
||||||
|
// Debug: Print proposal ID and number of ballots
|
||||||
|
println!(
|
||||||
|
"Extracting votes from proposal ID: {}",
|
||||||
|
proposal.base_data.id
|
||||||
|
);
|
||||||
|
println!("Number of ballots in proposal: {}", proposal.ballots.len());
|
||||||
|
|
||||||
|
// If there are no ballots, create some mock votes for testing
|
||||||
|
if proposal.ballots.is_empty() {
|
||||||
|
println!("No ballots found in proposal, creating mock votes for testing");
|
||||||
|
|
||||||
|
// Create mock votes based on the option counts
|
||||||
|
for option in &proposal.options {
|
||||||
|
if option.count > 0 {
|
||||||
|
let vote_type = match option.id {
|
||||||
|
1 => VoteType::Yes,
|
||||||
|
2 => VoteType::No,
|
||||||
|
3 => VoteType::Abstain,
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a mock vote for each count
|
||||||
|
for i in 0..option.count {
|
||||||
|
let vote = Vote::new(
|
||||||
|
proposal.base_data.id.to_string(),
|
||||||
|
i as i32 + 1,
|
||||||
|
format!("User {}", i + 1),
|
||||||
|
vote_type.clone(),
|
||||||
|
option.comment.clone(),
|
||||||
|
);
|
||||||
|
votes.push(vote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Created {} mock votes", votes.len());
|
||||||
|
return votes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert each ballot to a Vote
|
||||||
|
for (i, ballot) in proposal.ballots.iter().enumerate() {
|
||||||
|
println!(
|
||||||
|
"Processing ballot {}: user_id={}, option_id={}, shares={}",
|
||||||
|
i, ballot.user_id, ballot.vote_option_id, ballot.shares_count
|
||||||
|
);
|
||||||
|
|
||||||
|
// Map option_id to VoteType
|
||||||
|
let vote_type = match ballot.vote_option_id {
|
||||||
|
1 => VoteType::Yes,
|
||||||
|
2 => VoteType::No,
|
||||||
|
3 => VoteType::Abstain,
|
||||||
|
_ => {
|
||||||
|
println!(
|
||||||
|
"Unknown option_id: {}, defaulting to Abstain",
|
||||||
|
ballot.vote_option_id
|
||||||
|
);
|
||||||
|
VoteType::Abstain // Default to Abstain for unknown options
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert user_id from u32 to i32 safely
|
||||||
|
let voter_id = match i32::try_from(ballot.user_id) {
|
||||||
|
Ok(id) => id,
|
||||||
|
Err(e) => {
|
||||||
|
println!("Failed to convert user_id {} to i32: {}", ballot.user_id, e);
|
||||||
|
continue; // Skip this ballot if conversion fails
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a Vote from the ballot
|
||||||
|
let vote = Vote::new(
|
||||||
|
proposal.base_data.id.to_string(),
|
||||||
|
voter_id,
|
||||||
|
format!("User {}", voter_id),
|
||||||
|
vote_type,
|
||||||
|
ballot.comment.clone(), // Use the comment from the ballot
|
||||||
|
);
|
||||||
|
|
||||||
|
votes.push(vote);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Extracted {} votes from proposal", votes.len());
|
||||||
|
votes
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate mock statistics for the governance dashboard
|
/// Generate mock statistics for the governance dashboard
|
||||||
fn get_mock_statistics() -> GovernanceStats {
|
fn get_mock_statistics() -> GovernanceStats {
|
||||||
GovernanceStats {
|
GovernanceStats {
|
||||||
|
@ -4,11 +4,11 @@ use chrono::{Duration, Utc};
|
|||||||
use heromodels::db::hero::OurDB;
|
use heromodels::db::hero::OurDB;
|
||||||
use heromodels::{
|
use heromodels::{
|
||||||
db::{Collection, Db},
|
db::{Collection, Db},
|
||||||
models::governance::{Proposal, ProposalStatus, VoteEventStatus},
|
models::governance::{Proposal, ProposalStatus},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The path to the database file. Change this as needed for your environment.
|
/// The path to the database file. Change this as needed for your environment.
|
||||||
pub const DB_PATH: &str = "/tmp/ourdb_governance3";
|
pub const DB_PATH: &str = "/tmp/ourdb_governance6";
|
||||||
|
|
||||||
/// Returns a shared OurDB instance for the given path. You can wrap this in Arc/Mutex for concurrent access if needed.
|
/// Returns a shared OurDB instance for the given path. You can wrap this in Arc/Mutex for concurrent access if needed.
|
||||||
pub fn get_db(db_path: &str) -> Result<OurDB, String> {
|
pub fn get_db(db_path: &str) -> Result<OurDB, String> {
|
||||||
@ -97,6 +97,7 @@ pub fn submit_vote_on_proposal(
|
|||||||
user_id: i32,
|
user_id: i32,
|
||||||
vote_type: &str,
|
vote_type: &str,
|
||||||
shares_count: u32, // Default to 1 if not specified
|
shares_count: u32, // Default to 1 if not specified
|
||||||
|
comment: Option<String>,
|
||||||
) -> Result<Proposal, String> {
|
) -> Result<Proposal, String> {
|
||||||
// Get the proposal from the database
|
// Get the proposal from the database
|
||||||
let db = get_db(DB_PATH).map_err(|e| format!("DB error: {}", e))?;
|
let db = get_db(DB_PATH).map_err(|e| format!("DB error: {}", e))?;
|
||||||
@ -173,6 +174,23 @@ pub fn submit_vote_on_proposal(
|
|||||||
ballot_id, user_id, option_id, shares_count
|
ballot_id, user_id, option_id, shares_count
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Create a new ballot and add it to the proposal's ballots
|
||||||
|
use heromodels::models::governance::Ballot;
|
||||||
|
|
||||||
|
// Use the Ballot::new constructor which handles the BaseModelData creation
|
||||||
|
let mut ballot = Ballot::new(
|
||||||
|
Some(ballot_id),
|
||||||
|
user_id as u32,
|
||||||
|
option_id,
|
||||||
|
shares_count as i64,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set the comment if provided
|
||||||
|
ballot.comment = comment;
|
||||||
|
|
||||||
|
// Add the ballot to the proposal's ballots
|
||||||
|
proposal.ballots.push(ballot);
|
||||||
|
|
||||||
// Update the proposal's updated_at timestamp
|
// Update the proposal's updated_at timestamp
|
||||||
proposal.updated_at = Utc::now();
|
proposal.updated_at = Utc::now();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user