Going somewhere.
This commit is contained in:
1 parent
0d0337a6aa
commit
f140b50be4
17 files changed
+211
-20
No files matched your search
@@ -195,6 +195,31 @@ pub fn get_account_by_id(tx: &Connection, id: &AccountId) -> CustomResult<Accoun
|
||||
.map_err(Error::SqlError);
|
||||
}
|
||||
|
||||
pub fn get_checking_accounts_for_sec_id(tx: &Connection, sec_id: &SecurityId) -> CustomResult<Vec<Account>> {
|
||||
let q = "
|
||||
SELECT acc.id AS acc_id,
|
||||
acc.amount AS acc_amount,
|
||||
UNIXEPOCH(acc.timestamp) AS acc_timestamp,
|
||||
account_type AS acc_account_type,
|
||||
|
||||
sec.id AS sec_id,
|
||||
sec.symbol AS sec_symbol,
|
||||
sec.security_type AS sec_security_type,
|
||||
sec.name AS sec_name
|
||||
FROM accounts acc
|
||||
JOIN securities sec ON acc.security = sec.id
|
||||
WHERE sec.id = ?1";
|
||||
let mut stmt = tx.prepare(q).map_err(Error::SqlError)?;
|
||||
let ret: Vec<Account> = stmt
|
||||
.query_map(params![&sec_id], &Account::from_row)
|
||||
.map_err(Error::SqlError)?
|
||||
.filter(Result::is_ok)
|
||||
.map(Result::unwrap)
|
||||
.collect();
|
||||
return Ok(ret);
|
||||
|
||||
}
|
||||
|
||||
fn create_account(
|
||||
tx: &Connection,
|
||||
sec: &SecurityId,
|
||||
|
||||
@@ -125,7 +125,6 @@ macro_rules! impl_ids {
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct AccountId(SafeId);
|
||||
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct UserId(SafeId);
|
||||
|
||||
@@ -137,7 +136,7 @@ impl_ids!(UserId, "u");
|
||||
impl_ids!(SecurityId, "s");
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum ExternalId { // todo: perhaps this abstraction is useless.. duno
|
||||
enum ExternalId { // todo: perhaps this abstraction is useless.. duno
|
||||
AccountId(AccountId),
|
||||
UserId(UserId),
|
||||
SecurityId(SecurityId),
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ pub mod accounts {
|
||||
pub use super::_accounts::{
|
||||
add_to_account, create_checking_account, create_security_emitter_account,
|
||||
get_account_by_id, is_owner, list_accounts, Account, AccountChangeReceipt,
|
||||
list_user_accounts
|
||||
list_user_accounts, AccountType, get_checking_accounts_for_sec_id
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::db::accounts::{create_checking_account, create_security_emitter_accou
|
||||
|
||||
use crate::db::securities::create_security;
|
||||
use crate::db::users::create_user;
|
||||
use crate::events::{CreateNewAccount, CreateNewSecurity, CreateNewUser, Event};
|
||||
use crate::events::{CreateNewAccount, CreateNewSecurity, CreateNewUser, EmitSecurities, Event};
|
||||
use crate::util::{CustomResult, Error};
|
||||
|
||||
fn process_create_new_security_event(
|
||||
@@ -27,12 +27,19 @@ fn process_create_new_account_event(tx: &mut Transaction, event: CreateNewAccoun
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_emit_securities_event(tx: &mut Transaction, event: EmitSecurities) -> CustomResult<()> {
|
||||
// create_checking_account(&tx, &event.securityId, &event.userId)?;
|
||||
println!("Here it goes > {:?}", event);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn process_event(conn: &mut Connection, event: Event) -> CustomResult<()> {
|
||||
let mut tx = conn.transaction().map_err(Error::SqlError)?;
|
||||
match event {
|
||||
Event::CreateNewSecurity(e) => process_create_new_security_event(&mut tx, e)?,
|
||||
Event::CreateNewUser(e) => process_create_new_user_event(&mut tx, e)?,
|
||||
Event::CreateNewAccount(e) => process_create_new_account_event(&mut tx, e)?,
|
||||
Event::EmitSecurities(e) => process_emit_securities_event(&mut tx, e)?,
|
||||
};
|
||||
tx.commit().map_err(Error::SqlError)
|
||||
}
|
||||
+9
-1
@@ -1,5 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::db::external_id::{SecurityId, UserId};
|
||||
use crate::db::external_id::{AccountId, SecurityId, UserId};
|
||||
|
||||
use crate::db::securities::{NewSecurity, SecurityType};
|
||||
|
||||
@@ -44,11 +44,19 @@ pub struct CreateNewAccount {
|
||||
pub userId: UserId,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct EmitSecurities {
|
||||
pub amount: i64,
|
||||
pub emitter_account: AccountId,
|
||||
pub payee_accounts: Vec<AccountId>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub enum Event {
|
||||
CreateNewSecurity(CreateNewSecurity),
|
||||
CreateNewUser(CreateNewUser),
|
||||
CreateNewAccount(CreateNewAccount),
|
||||
EmitSecurities(EmitSecurities),
|
||||
}
|
||||
|
||||
impl Event {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use rusqlite::Connection;
|
||||
use crate::db::accounts::{Account, list_user_accounts};
|
||||
use crate::db::external_id::{Id, UserId};
|
||||
use crate::db::accounts::{Account, AccountType, get_checking_accounts_for_sec_id, list_user_accounts};
|
||||
use crate::db::external_id::{Id, SecurityId, UserId};
|
||||
use crate::util::{CustomResult, Error};
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use crate::db::securities::Security;
|
||||
use crate::services::_securities::SecurityDTO;
|
||||
|
||||
pub struct AccountService<'a> {
|
||||
conn: &'a Connection,
|
||||
}
|
||||
@@ -14,7 +17,7 @@ pub struct AccountDTO {
|
||||
pub amount: i64,
|
||||
pub account_type: String,
|
||||
pub last_update: i64,
|
||||
pub security_symbol: String,
|
||||
pub security: SecurityDTO,
|
||||
}
|
||||
|
||||
impl AccountDTO {
|
||||
@@ -24,7 +27,7 @@ impl AccountDTO {
|
||||
amount: account.amount(),
|
||||
account_type: account.account_type().to_string(),
|
||||
last_update: account.timestamp(),
|
||||
security_symbol: account.security().symbol()
|
||||
security: SecurityDTO::from_entity(account.security())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,4 +46,17 @@ impl AccountService<'_> {
|
||||
Ok(ret.iter().map(AccountDTO::from_entity).collect())
|
||||
}
|
||||
|
||||
pub fn get_user_emitter_accounts(& self, user_id: &UserId) -> CustomResult<Vec<AccountDTO>> {
|
||||
let accounts = self.get_user_accounts(user_id)?;
|
||||
let ret = accounts.into_iter()
|
||||
.filter(|acc| acc.account_type == AccountType::SecurityEmitter.to_string())
|
||||
.collect();
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn get_checking_accounts_for_security(& self, sec_id: & SecurityId) -> CustomResult<Vec<AccountDTO>>{
|
||||
let ret = get_checking_accounts_for_sec_id(self.conn, sec_id)?;
|
||||
Ok(ret.iter().map(AccountDTO::from_entity).collect())
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ use crate::db::securities::{list_securities, Security};
|
||||
use rusqlite::Connection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct SecurityDTO {
|
||||
id: SecurityId,
|
||||
symbol: String,
|
||||
@@ -12,7 +12,7 @@ pub struct SecurityDTO {
|
||||
}
|
||||
|
||||
impl SecurityDTO {
|
||||
fn from_entity(sec: &Security) -> SecurityDTO {
|
||||
pub fn from_entity(sec: &Security) -> SecurityDTO {
|
||||
SecurityDTO {
|
||||
id: sec.id(),
|
||||
symbol: sec.symbol(),
|
||||
|
||||
@@ -67,10 +67,13 @@ fn create_views_scope() -> Scope {
|
||||
.service(index_views::logout)
|
||||
.service(views::actions)
|
||||
.service(views::accounts)
|
||||
.service(views::account)
|
||||
.service(views::securities)
|
||||
.service(views::security)
|
||||
.service(views::overview)
|
||||
.service(views::overview_submit_button)
|
||||
.service(views::actions_partials)
|
||||
.service(views::get_accounts_by_security_selectors)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
||||
+57
-1
@@ -8,6 +8,7 @@ use minijinja::context;
|
||||
use rusqlite::params;
|
||||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
use crate::db::external_id::{Id, SecurityId};
|
||||
|
||||
use crate::events::Event;
|
||||
|
||||
@@ -32,6 +33,14 @@ pub async fn accounts(tmpl_env: MiniJinjaRenderer,
|
||||
tmpl_env.render("accounts.html", context!{accounts => accounts})
|
||||
}
|
||||
|
||||
#[actix_web::get("/accounts/{account_id}")]
|
||||
pub async fn account(tmpl_env: MiniJinjaRenderer,
|
||||
req: HttpRequest,
|
||||
service_factory: web::Data<ServicesFactory>) -> actix_web::Result<impl Responder> {
|
||||
|
||||
tmpl_env.render("account.html", context!{})
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[actix_web::get("/securities")]
|
||||
@@ -45,6 +54,14 @@ pub async fn securities(tmpl_env: MiniJinjaRenderer,
|
||||
tmpl_env.render("securities.html", ctx)
|
||||
}
|
||||
|
||||
#[actix_web::get("/securities/{sec_id}")]
|
||||
pub async fn security(tmpl_env: MiniJinjaRenderer,
|
||||
service_factory: web::Data<ServicesFactory>) -> actix_web::Result<impl Responder> {
|
||||
|
||||
let ctx = context!{};
|
||||
tmpl_env.render("security.html", ctx)
|
||||
}
|
||||
|
||||
#[actix_web::get("/overview")]
|
||||
pub async fn overview(
|
||||
tmpl_env: MiniJinjaRenderer,
|
||||
@@ -71,6 +88,37 @@ pub async fn overview_submit_button(
|
||||
tmpl_env.render("partials/overview/submit_button.html", ctx)
|
||||
}
|
||||
|
||||
|
||||
#[actix_web::get("/partials/actions/accounts-by-security-selectors")]
|
||||
pub async fn get_accounts_by_security_selectors(
|
||||
req: HttpRequest,
|
||||
tmpl_env: MiniJinjaRenderer,
|
||||
query: web::Query<HashMap<String, String>>,
|
||||
service_factory: web::Data<ServicesFactory>,
|
||||
) -> actix_web::Result<Html> {
|
||||
let sec_id = query
|
||||
.get("sec-id")
|
||||
.and_then(SecurityId::from_string)
|
||||
.ok_or(error::ErrorBadRequest("Invalid sec-id parameters"))?;
|
||||
let conn = service_factory.get_connection()?;
|
||||
let account_service = service_factory.get_account_service(&conn)?;
|
||||
let authentication_service = service_factory.get_authentication_service(&conn)?;
|
||||
|
||||
let maybe_user = authentication_service.get_login(&req);
|
||||
if maybe_user.is_none() {
|
||||
return Err(error::ErrorForbidden(""))
|
||||
}
|
||||
let user_id = maybe_user.unwrap();
|
||||
|
||||
let ctx = context! {
|
||||
sec_id => &sec_id,
|
||||
user_id => &user_id,
|
||||
accounts => account_service.get_checking_accounts_for_security(&sec_id).map_err(error::ErrorInternalServerError)?,
|
||||
};
|
||||
tmpl_env.render("partials/actions/accounts-by-security-selectors.html", ctx)
|
||||
}
|
||||
|
||||
|
||||
#[actix_web::get("/partials/actions/action-form")]
|
||||
pub async fn actions_partials(
|
||||
req: HttpRequest,
|
||||
@@ -84,11 +132,19 @@ pub async fn actions_partials(
|
||||
.to_string();
|
||||
let conn = service_factory.get_connection()?;
|
||||
let security_service = service_factory.get_security_service(&conn)?;
|
||||
let account_service = service_factory.get_account_service(&conn)?;
|
||||
let authentication_service = service_factory.get_authentication_service(&conn)?;
|
||||
let maybeUser = authentication_service.get_login(&req);
|
||||
if maybeUser.is_none() {
|
||||
return Err(actix_web::error::ErrorForbidden(""))
|
||||
}
|
||||
let user = maybeUser.unwrap();
|
||||
let ctx = context! {
|
||||
event_type => event_type,
|
||||
securities => security_service.list_securities(),
|
||||
user => authentication_service.get_logged_in_user(&req).map_err(actix_web::error::ErrorInternalServerError)?,
|
||||
emitter_accounts => account_service.get_user_emitter_accounts(&user).map_err(error::ErrorInternalServerError)?,
|
||||
accounts => account_service.get_user_emitter_accounts(&user).map_err(error::ErrorInternalServerError)?,
|
||||
user => authentication_service.get_logged_in_user(&req).map_err(error::ErrorInternalServerError)?,
|
||||
};
|
||||
let template_location = format!("partials/actions/{:}.html", event_type);
|
||||
info!("Getting template at: {:?}", template_location);
|
||||
|
||||
Reference in new issue
Block a user