Add company management module with registration and entity switching
This commit is contained in:
245
actix_mvc_app/src/controllers/company.rs
Normal file
245
actix_mvc_app/src/controllers/company.rs
Normal file
@@ -0,0 +1,245 @@
|
||||
use actix_web::{web, HttpResponse, Responder, Result};
|
||||
use actix_web::HttpRequest;
|
||||
use tera::{Context, Tera};
|
||||
use serde::Deserialize;
|
||||
use chrono::Utc;
|
||||
use crate::utils::render_template;
|
||||
|
||||
// Form structs for company operations
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CompanyRegistrationForm {
|
||||
pub company_name: String,
|
||||
pub company_type: String,
|
||||
pub shareholders: String,
|
||||
pub company_purpose: Option<String>,
|
||||
}
|
||||
|
||||
pub struct CompanyController;
|
||||
|
||||
impl CompanyController {
|
||||
// Display the company management dashboard
|
||||
pub async fn index(tmpl: web::Data<Tera>, req: HttpRequest) -> Result<HttpResponse> {
|
||||
let mut context = Context::new();
|
||||
|
||||
println!("DEBUG: Starting Company dashboard rendering");
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"company");
|
||||
|
||||
// Parse query parameters
|
||||
let query_string = req.query_string();
|
||||
|
||||
// Check for success message
|
||||
if let Some(pos) = query_string.find("success=") {
|
||||
let start = pos + 8; // length of "success="
|
||||
let end = query_string[start..].find('&').map_or(query_string.len(), |e| e + start);
|
||||
let success = &query_string[start..end];
|
||||
let decoded = urlencoding::decode(success).unwrap_or_else(|_| success.into());
|
||||
context.insert("success", &decoded);
|
||||
}
|
||||
|
||||
// Check for entity context
|
||||
if let Some(pos) = query_string.find("entity=") {
|
||||
let start = pos + 7; // length of "entity="
|
||||
let end = query_string[start..].find('&').map_or(query_string.len(), |e| e + start);
|
||||
let entity = &query_string[start..end];
|
||||
context.insert("entity", &entity);
|
||||
|
||||
// Also get entity name if present
|
||||
if let Some(pos) = query_string.find("entity_name=") {
|
||||
let start = pos + 12; // length of "entity_name="
|
||||
let end = query_string[start..].find('&').map_or(query_string.len(), |e| e + start);
|
||||
let entity_name = &query_string[start..end];
|
||||
let decoded_name = urlencoding::decode(entity_name).unwrap_or_else(|_| entity_name.into());
|
||||
context.insert("entity_name", &decoded_name);
|
||||
println!("DEBUG: Entity context set to {} ({})", entity, decoded_name);
|
||||
}
|
||||
}
|
||||
|
||||
println!("DEBUG: Rendering Company dashboard template");
|
||||
let response = render_template(&tmpl, "company/index.html", &context);
|
||||
println!("DEBUG: Finished rendering Company dashboard template");
|
||||
response
|
||||
}
|
||||
|
||||
// View company details
|
||||
pub async fn view_company(tmpl: web::Data<Tera>, path: web::Path<String>) -> Result<HttpResponse> {
|
||||
let company_id = path.into_inner();
|
||||
let mut context = Context::new();
|
||||
|
||||
println!("DEBUG: Viewing company details for {}", company_id);
|
||||
|
||||
// Add active_page for navigation highlighting
|
||||
context.insert("active_page", &"company");
|
||||
context.insert("company_id", &company_id);
|
||||
|
||||
// In a real application, we would fetch company data from a database
|
||||
// For now, we'll use mock data based on the company_id
|
||||
match company_id.as_str() {
|
||||
"company1" => {
|
||||
context.insert("company_name", &"Zanzibar Digital Solutions");
|
||||
context.insert("company_type", &"Startup FZC");
|
||||
context.insert("status", &"Active");
|
||||
context.insert("registration_date", &"2025-04-01");
|
||||
context.insert("purpose", &"Digital solutions and blockchain development");
|
||||
context.insert("plan", &"Startup FZC - $50/month");
|
||||
context.insert("next_billing", &"2025-06-01");
|
||||
context.insert("payment_method", &"Credit Card (****4582)");
|
||||
|
||||
// Shareholders data
|
||||
let shareholders = vec![
|
||||
("John Smith", "60%"),
|
||||
("Sarah Johnson", "40%"),
|
||||
];
|
||||
context.insert("shareholders", &shareholders);
|
||||
|
||||
// Contracts data
|
||||
let contracts = vec![
|
||||
("Articles of Incorporation", "Signed"),
|
||||
("Terms & Conditions", "Signed"),
|
||||
("Digital Asset Issuance", "Signed"),
|
||||
];
|
||||
context.insert("contracts", &contracts);
|
||||
},
|
||||
"company2" => {
|
||||
context.insert("company_name", &"Blockchain Innovations Ltd");
|
||||
context.insert("company_type", &"Growth FZC");
|
||||
context.insert("status", &"Active");
|
||||
context.insert("registration_date", &"2025-03-15");
|
||||
context.insert("purpose", &"Blockchain technology research and development");
|
||||
context.insert("plan", &"Growth FZC - $100/month");
|
||||
context.insert("next_billing", &"2025-06-15");
|
||||
context.insert("payment_method", &"Bank Transfer");
|
||||
|
||||
// Shareholders data
|
||||
let shareholders = vec![
|
||||
("Michael Chen", "35%"),
|
||||
("Aisha Patel", "35%"),
|
||||
("David Okonkwo", "30%"),
|
||||
];
|
||||
context.insert("shareholders", &shareholders);
|
||||
|
||||
// Contracts data
|
||||
let contracts = vec![
|
||||
("Articles of Incorporation", "Signed"),
|
||||
("Terms & Conditions", "Signed"),
|
||||
("Digital Asset Issuance", "Signed"),
|
||||
("Physical Asset Holding", "Signed"),
|
||||
];
|
||||
context.insert("contracts", &contracts);
|
||||
},
|
||||
"company3" => {
|
||||
context.insert("company_name", &"Sustainable Energy Cooperative");
|
||||
context.insert("company_type", &"Cooperative FZC");
|
||||
context.insert("status", &"Pending");
|
||||
context.insert("registration_date", &"2025-05-01");
|
||||
context.insert("purpose", &"Renewable energy production and distribution");
|
||||
context.insert("plan", &"Cooperative FZC - $200/month");
|
||||
context.insert("next_billing", &"Pending Activation");
|
||||
context.insert("payment_method", &"Pending");
|
||||
|
||||
// Shareholders data
|
||||
let shareholders = vec![
|
||||
("Community Energy Group", "40%"),
|
||||
("Green Future Initiative", "30%"),
|
||||
("Sustainable Living Collective", "30%"),
|
||||
];
|
||||
context.insert("shareholders", &shareholders);
|
||||
|
||||
// Contracts data
|
||||
let contracts = vec![
|
||||
("Articles of Incorporation", "Signed"),
|
||||
("Terms & Conditions", "Signed"),
|
||||
("Cooperative Governance", "Pending"),
|
||||
];
|
||||
context.insert("contracts", &contracts);
|
||||
},
|
||||
_ => {
|
||||
// If company_id is not recognized, redirect to company index
|
||||
return Ok(HttpResponse::Found()
|
||||
.append_header(("Location", "/company"))
|
||||
.finish());
|
||||
}
|
||||
}
|
||||
|
||||
println!("DEBUG: Rendering company view template");
|
||||
let response = render_template(&tmpl, "company/view.html", &context);
|
||||
println!("DEBUG: Finished rendering company view template");
|
||||
response
|
||||
}
|
||||
|
||||
// Switch to entity context
|
||||
pub async fn switch_entity(path: web::Path<String>) -> Result<HttpResponse> {
|
||||
let company_id = path.into_inner();
|
||||
|
||||
println!("DEBUG: Switching to entity context for {}", company_id);
|
||||
|
||||
// Get company name based on ID (in a real app, this would come from a database)
|
||||
let company_name = match company_id.as_str() {
|
||||
"company1" => "Zanzibar Digital Solutions",
|
||||
"company2" => "Blockchain Innovations Ltd",
|
||||
"company3" => "Sustainable Energy Cooperative",
|
||||
_ => "Unknown Company"
|
||||
};
|
||||
|
||||
// In a real application, we would set a session/cookie for the current entity
|
||||
// Here we'll redirect back to the company page with a success message and entity parameter
|
||||
let success_message = format!("Switched to {} entity context", company_name);
|
||||
let encoded_message = urlencoding::encode(&success_message);
|
||||
|
||||
Ok(HttpResponse::Found()
|
||||
.append_header(("Location", format!("/company?success={}&entity={}&entity_name={}",
|
||||
encoded_message, company_id, urlencoding::encode(company_name))))
|
||||
.finish())
|
||||
}
|
||||
|
||||
// Process company registration
|
||||
pub async fn register(
|
||||
mut form: actix_multipart::Multipart,
|
||||
) -> Result<HttpResponse> {
|
||||
use actix_web::{http::header};
|
||||
use futures_util::stream::StreamExt as _;
|
||||
use std::collections::HashMap;
|
||||
|
||||
println!("DEBUG: Processing company registration request");
|
||||
|
||||
let mut fields: HashMap<String, String> = HashMap::new();
|
||||
let mut files = Vec::new();
|
||||
|
||||
// Parse multipart form
|
||||
while let Some(Ok(mut field)) = form.next().await {
|
||||
let mut value = Vec::new();
|
||||
while let Some(chunk) = field.next().await {
|
||||
let data = chunk.unwrap();
|
||||
value.extend_from_slice(&data);
|
||||
}
|
||||
|
||||
// Get field name from content disposition
|
||||
let cd = field.content_disposition();
|
||||
if let Some(name) = cd.get_name() {
|
||||
if name == "company_docs" {
|
||||
files.push(value); // Just collect files in memory for now
|
||||
} else {
|
||||
fields.insert(name.to_string(), String::from_utf8_lossy(&value).to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract company details
|
||||
let company_name = fields.get("company_name").cloned().unwrap_or_default();
|
||||
let company_type = fields.get("company_type").cloned().unwrap_or_default();
|
||||
let shareholders = fields.get("shareholders").cloned().unwrap_or_default();
|
||||
|
||||
// Log received fields (mock DB insert)
|
||||
println!("[Company Registration] Name: {}, Type: {}, Shareholders: {}, Files: {}",
|
||||
company_name, company_type, shareholders, files.len());
|
||||
|
||||
// Create success message
|
||||
let success_message = format!("Successfully registered {} as a {}", company_name, company_type);
|
||||
|
||||
// Redirect back to /company with success message
|
||||
Ok(HttpResponse::SeeOther()
|
||||
.append_header((header::LOCATION, format!("/company?success={}", urlencoding::encode(&success_message))))
|
||||
.finish())
|
||||
}
|
||||
}
|
@@ -9,5 +9,6 @@ pub mod contract;
|
||||
pub mod asset;
|
||||
pub mod defi;
|
||||
pub mod marketplace;
|
||||
pub mod company;
|
||||
|
||||
// Re-export controllers for easier imports
|
||||
|
Reference in New Issue
Block a user