122 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
use crate::connections::db_connection::db;
 | 
						|
use crate::controllers::server_controller::ServerConstraints;
 | 
						|
use crate::models::files::FileID;
 | 
						|
use crate::models::inbox::{InboxEntry, InboxEntryID, NewInboxEntry};
 | 
						|
use crate::models::movements::MovementID;
 | 
						|
use crate::models::users::UserID;
 | 
						|
use crate::schema::inbox;
 | 
						|
use crate::services::{accounts_service, files_service, movements_service};
 | 
						|
use crate::utils::time_utils::time;
 | 
						|
use diesel::prelude::*;
 | 
						|
 | 
						|
#[derive(serde::Deserialize)]
 | 
						|
pub struct UpdateInboxEntryQuery {
 | 
						|
    pub file_id: FileID,
 | 
						|
    pub movement_id: Option<MovementID>,
 | 
						|
    pub time: u64,
 | 
						|
    pub label: Option<String>,
 | 
						|
    pub amount: Option<f32>,
 | 
						|
}
 | 
						|
 | 
						|
impl UpdateInboxEntryQuery {
 | 
						|
    pub async fn check_error(&self, user_id: UserID) -> anyhow::Result<Option<&'static str>> {
 | 
						|
        let constraints = ServerConstraints::default();
 | 
						|
 | 
						|
        // Check inbox entry label
 | 
						|
        if let Some(label) = &self.label {
 | 
						|
            if !constraints.inbox_entry_label.check_str(label) {
 | 
						|
                return Ok(Some("Invalid inbox entry label length!"));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // Check the referenced movement
 | 
						|
        if let Some(movement_id) = self.movement_id {
 | 
						|
            let Ok(movement) = movements_service::get_by_id(movement_id).await else {
 | 
						|
                return Ok(Some("Movement not found"));
 | 
						|
            };
 | 
						|
 | 
						|
            let account = accounts_service::get_by_id(movement.account_id()).await?;
 | 
						|
 | 
						|
            if account.user_id() != user_id {
 | 
						|
                return Ok(Some("The account does not own this movement!"));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // Check the file
 | 
						|
        let Ok(file) = files_service::get_file_with_id(self.file_id) else {
 | 
						|
            return Ok(Some("The account does not own this file!"));
 | 
						|
        };
 | 
						|
        if file.user_id() != user_id {
 | 
						|
            return Ok(Some("The user does not own the referenced file!"));
 | 
						|
        }
 | 
						|
 | 
						|
        Ok(None)
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/// Create a new inbox entry
 | 
						|
pub async fn create(user_id: UserID, query: &UpdateInboxEntryQuery) -> anyhow::Result<InboxEntry> {
 | 
						|
    let new_entry = NewInboxEntry {
 | 
						|
        time: query.time as i64,
 | 
						|
        label: query.label.as_deref(),
 | 
						|
        file_id: query.file_id.0,
 | 
						|
        user_id: user_id.0,
 | 
						|
        amount: query.amount,
 | 
						|
        time_create: time() as i64,
 | 
						|
        time_update: time() as i64,
 | 
						|
        movement_id: None,
 | 
						|
    };
 | 
						|
 | 
						|
    let res: InboxEntry = diesel::insert_into(inbox::table)
 | 
						|
        .values(&new_entry)
 | 
						|
        .get_result(&mut db()?)?;
 | 
						|
 | 
						|
    update(res.id(), query).await?;
 | 
						|
 | 
						|
    Ok(res)
 | 
						|
}
 | 
						|
 | 
						|
/// Update a inbox entry
 | 
						|
pub async fn update(id: InboxEntryID, q: &UpdateInboxEntryQuery) -> anyhow::Result<()> {
 | 
						|
    diesel::update(inbox::dsl::inbox.filter(inbox::dsl::id.eq(id.0)))
 | 
						|
        .set((
 | 
						|
            inbox::dsl::time_update.eq(time() as i64),
 | 
						|
            inbox::dsl::movement_id.eq(q.movement_id.map(|m| m.0)),
 | 
						|
            inbox::dsl::time.eq(q.time as i64),
 | 
						|
            inbox::dsl::label.eq(&q.label),
 | 
						|
            inbox::dsl::file_id.eq(&q.file_id.0),
 | 
						|
            inbox::dsl::amount.eq(q.amount),
 | 
						|
        ))
 | 
						|
        .execute(&mut db()?)?;
 | 
						|
 | 
						|
    Ok(())
 | 
						|
}
 | 
						|
 | 
						|
/// Get the full list of inbox entries of a user
 | 
						|
pub async fn get_list_user(user_id: UserID) -> anyhow::Result<Vec<InboxEntry>> {
 | 
						|
    Ok(inbox::table
 | 
						|
        .filter(inbox::dsl::user_id.eq(user_id.0))
 | 
						|
        .get_results(&mut db()?)?)
 | 
						|
}
 | 
						|
 | 
						|
/// Get a single inbox entry by its ID
 | 
						|
pub async fn get_by_id(entry_id: InboxEntryID) -> anyhow::Result<InboxEntry> {
 | 
						|
    Ok(inbox::table
 | 
						|
        .filter(inbox::dsl::id.eq(entry_id.0))
 | 
						|
        .get_result(&mut db()?)?)
 | 
						|
}
 | 
						|
 | 
						|
/// Delete an inbox entry
 | 
						|
pub async fn delete(id: InboxEntryID) -> anyhow::Result<()> {
 | 
						|
    diesel::delete(inbox::dsl::inbox.filter(inbox::dsl::id.eq(id.0))).execute(&mut db()?)?;
 | 
						|
    Ok(())
 | 
						|
}
 | 
						|
 | 
						|
/// Delete all the inbox entries of a user
 | 
						|
pub async fn delete_all_user(user: UserID) -> anyhow::Result<()> {
 | 
						|
    for inbox_entry in get_list_user(user).await? {
 | 
						|
        delete(inbox_entry.id()).await?;
 | 
						|
    }
 | 
						|
    Ok(())
 | 
						|
}
 |