Skip to content

Commit

Permalink
Merge pull request #138 from LRZ-BADW/user-budget-sync
Browse files Browse the repository at this point in the history
User Budget Sync
  • Loading branch information
gierens authored Dec 28, 2024
2 parents f57bd91 + e51746d commit f9b9afb
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 1 deletion.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions api/src/database/budgeting/user_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,29 @@ pub async fn insert_user_budget_into_db(
let id = result.last_insert_id();
Ok(id)
}

#[tracing::instrument(name = "sync_user_budgets_in_db", skip(transaction))]
pub async fn sync_user_budgets_in_db(
transaction: &mut Transaction<'_, MySql>,
) -> Result<u64, MinimalApiError> {
let year = 2024;
let query = sqlx::query!(
r#"
UPDATE
budgeting_userbudget AS c,
budgeting_userbudget AS n
SET n.amount = c.amount
WHERE c.user_id = n.user_id
AND c.year = ?
AND n.year = ?
AND c.amount != n.amount
"#,
year,
year + 1
);
let result = transaction
.execute(query)
.await
.context("Failed to execute insert query")?;
Ok(result.rows_affected())
}
3 changes: 3 additions & 0 deletions api/src/routes/budgeting/user_budget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ mod modify;
use modify::user_budget_modify;
mod delete;
use delete::user_budget_delete;
mod sync;
use sync::user_budget_sync;

pub fn user_budgets_scope() -> Scope {
scope("/userbudgets")
Expand All @@ -21,6 +23,7 @@ pub fn user_budgets_scope() -> Scope {
// TODO: what about PUT?
.route("/{user_budget_id}/", patch().to(user_budget_modify))
.route("/{user_budget_id}/", delete().to(user_budget_delete))
.route("/sync/", get().to(user_budget_sync))
}

// TODO: wouldn't a general IdParam be better?
Expand Down
34 changes: 34 additions & 0 deletions api/src/routes/budgeting/user_budget/sync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use crate::authorization::require_admin_user;
use crate::database::budgeting::user_budget::sync_user_budgets_in_db;
use crate::error::NormalApiError;
use actix_web::web::{Data, ReqData};
use actix_web::HttpResponse;
use anyhow::Context;
use lrzcc_wire::budgeting::UserBudgetSync;
use lrzcc_wire::user::{Project, User};
use sqlx::MySqlPool;

// TODO: write tests for this endpoint
#[tracing::instrument(name = "user_budget_sync")]
pub async fn user_budget_sync(
user: ReqData<User>,
project: ReqData<Project>,
db_pool: Data<MySqlPool>,
// TODO: this can only be an authorization or unexpected error, we need a type for that
) -> Result<HttpResponse, NormalApiError> {
require_admin_user(&user)?;
let mut transaction = db_pool
.begin()
.await
.context("Failed to begin transaction")?;
let count = sync_user_budgets_in_db(&mut transaction).await?;
transaction
.commit()
.await
.context("Failed to commit transaction")?;
Ok(HttpResponse::Ok().content_type("application/json").json(
UserBudgetSync {
updated_budget_count: count as u32,
},
))
}
8 changes: 8 additions & 0 deletions cli/src/budgeting/user_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ pub(crate) enum UserBudgetCommand {
)]
detail: bool,
},

#[clap(about = "Sync user budgets of next year to those to this one")]
Sync,
}
pub(crate) use UserBudgetCommand::*;

Expand All @@ -157,6 +160,7 @@ impl Execute for UserBudgetCommand {
combined,
detail,
} => over(api, format, filter, *end, *combined, *detail),
Sync => sync(api, format),
}
}
}
Expand Down Expand Up @@ -262,3 +266,7 @@ fn over(
(true, true) => print_object_list(request.combined_detail()?, format),
}
}

fn sync(api: lrzcc::Api, format: Format) -> Result<(), Box<dyn Error>> {
print_single_object(api.user_budget.sync()?, format)
}
13 changes: 12 additions & 1 deletion lib/src/budgeting/user_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use chrono::{DateTime, FixedOffset};
use lrzcc_wire::budgeting::{
UserBudget, UserBudgetCombined, UserBudgetCombinedDetail,
UserBudgetCreateData, UserBudgetDetail, UserBudgetListParams,
UserBudgetModifyData, UserBudgetOver,
UserBudgetModifyData, UserBudgetOver, UserBudgetSync,
};
use reqwest::blocking::Client;
use reqwest::Url;
Expand Down Expand Up @@ -354,4 +354,15 @@ impl UserBudgetApi {
let url = format!("{}/over/", self.url);
UserBudgetOverRequest::new(url.as_ref(), &self.client)
}

pub fn sync(&self) -> Result<UserBudgetSync, ApiError> {
let url = format!("{}/sync/", self.url);
request(
&self.client,
Method::GET,
url.as_str(),
SerializableNone!(),
StatusCode::OK,
)
}
}
5 changes: 5 additions & 0 deletions wire/src/budgeting/user_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,8 @@ pub struct UserBudgetCombinedDetail {
pub user_cost: f64,
pub user_budget: u32,
}

#[derive(Clone, Debug, Deserialize, Serialize, Tabled, PartialEq)]
pub struct UserBudgetSync {
pub updated_budget_count: u32,
}

0 comments on commit f9b9afb

Please sign in to comment.