diff --git a/db/sql/user/read_by_availability_id.sql b/db/sql/user/read_by_availability_id.sql new file mode 100644 index 00000000..0e1ba274 --- /dev/null +++ b/db/sql/user/read_by_availability_id.sql @@ -0,0 +1,20 @@ +SELECT + user_.id, + name, + email, + password, + salt, + role AS "role: Role", + function AS "function: UserFunction", + areaId, + locked, + lastLogin, + receiveNotifications +FROM + user_, + availability +WHERE + availability.id = $1 + AND availability.userId = user_.id +ORDER BY + id; diff --git a/db/src/models/user.rs b/db/src/models/user.rs index a139f51a..fde16f08 100644 --- a/db/src/models/user.rs +++ b/db/src/models/user.rs @@ -1,5 +1,5 @@ use chrono::{DateTime, Utc}; -use sqlx::PgPool; +use sqlx::{PgPool, query_file}; use super::{Area, Function, Result, Role, UserChangeset, UserFunction}; @@ -290,6 +290,32 @@ impl User { Ok(result) } + pub async fn read_by_availability_id( + pool: &PgPool, + availability_id: i32, + ) -> Result> { + let record = query_file!("sql/user/read_by_availability_id.sql", availability_id) + .fetch_optional(pool) + .await?; + + let result = record.map(|r| User { + id: r.id, + name: r.name.clone(), + email: r.email.clone(), + password: r.password.clone(), + salt: r.salt.clone(), + role: r.role, + function: r.function.clone(), + area_id: r.areaid, + area: None, + locked: r.locked, + last_login: r.lastlogin, + receive_notifications: r.receivenotifications, + }); + + Ok(result) + } + pub async fn update(pool: &PgPool, id: i32, changeset: UserChangeset) -> Result<()> { sqlx::query!( "UPDATE user_ SET name = $1, email = $2, role = $3, function = $4, areaId = $5 WHERE id = $6;", diff --git a/web/src/endpoints/assignment/delete.rs b/web/src/endpoints/assignment/delete.rs index 912e45a9..42ce1e34 100644 --- a/web/src/endpoints/assignment/delete.rs +++ b/web/src/endpoints/assignment/delete.rs @@ -4,6 +4,7 @@ use sqlx::PgPool; use crate::{ endpoints::assignment::PlanEventPersonalTablePartialTemplate, + mail::Mailer, utils::{ event_planning_template::{ generate_availability_assignment_list, generate_status_whether_staff_is_required, @@ -24,6 +25,7 @@ pub async fn delete( user: web::ReqData, pool: web::Data, query: web::Query, + mailer: web::Data, ) -> Result { let Some(event) = Event::read_by_id_including_location(pool.get_ref(), query.event).await? else { @@ -45,6 +47,16 @@ pub async fn delete( Assignment::delete(pool.get_ref(), event.id, assignment.availability_id).await?; + let user_of_availability = + User::read_by_availability_id(pool.get_ref(), assignment.availability_id) + .await? + .unwrap(); + if user_of_availability.receive_notifications { + mailer + .send_assignment_deleted_mail(&user_of_availability, &assignment.function, &event) + .await?; + } + let availabilities = generate_availability_assignment_list(pool.get_ref(), &event).await?; let ( further_posten_required, diff --git a/web/src/endpoints/assignment/post_new.rs b/web/src/endpoints/assignment/post_new.rs index 711d511b..1e823082 100644 --- a/web/src/endpoints/assignment/post_new.rs +++ b/web/src/endpoints/assignment/post_new.rs @@ -4,6 +4,7 @@ use sqlx::PgPool; use crate::{ endpoints::assignment::PlanEventPersonalTablePartialTemplate, + mail::Mailer, utils::{ event_planning_template::{ generate_availability_assignment_list, generate_status_whether_staff_is_required, @@ -29,6 +30,7 @@ pub async fn post( user: web::ReqData, pool: web::Data, query: web::Query, + mailer: web::Data, ) -> Result { if user.role != Role::Admin && user.role != Role::AreaManager { return Err(ApplicationError::Unauthorized); @@ -59,6 +61,16 @@ pub async fn post( Assignment::create(pool.get_ref(), event.id, query.availability, changeset).await?; + let user_of_availability = + User::read_by_availability_id(pool.get_ref(), context.availability_id) + .await? + .unwrap(); + if user_of_availability.receive_notifications { + mailer + .send_assignment_created_mail(&user_of_availability, &function, &event) + .await?; + } + let availabilities = generate_availability_assignment_list(pool.get_ref(), &event).await?; let ( diff --git a/web/src/mail/notify_planned.rs b/web/src/mail/notify_planned.rs index baa78005..ca461913 100644 --- a/web/src/mail/notify_planned.rs +++ b/web/src/mail/notify_planned.rs @@ -1,5 +1,5 @@ use askama::Template; -use brass_db::models::{Assignment, Event, Function, User}; +use brass_db::models::{Event, Function, User}; use lettre::{ message::{Mailbox, MultiPart, SinglePart}, Address, AsyncTransport, Message, @@ -18,14 +18,14 @@ impl Mailer { pub async fn send_assignment_created_mail( &self, user: &User, - assignment: &Assignment, + assigned_function: &Function, event: &Event, ) -> Result<(), ApplicationError> { let message = build( &self.hostname, &user.name, &user.email, - &assignment.function, + &assigned_function, event, )?; self.transport.send(message).await?; diff --git a/web/src/mail/notify_unplanned.rs b/web/src/mail/notify_unplanned.rs index d2e66f6d..4cc6eba1 100644 --- a/web/src/mail/notify_unplanned.rs +++ b/web/src/mail/notify_unplanned.rs @@ -1,5 +1,5 @@ use askama::Template; -use brass_db::models::{Assignment, Event, Function, User}; +use brass_db::models::{Event, Function, User}; use lettre::{ message::{Mailbox, MultiPart, SinglePart}, Address, AsyncTransport, Message, @@ -18,14 +18,14 @@ impl Mailer { pub async fn send_assignment_deleted_mail( &self, user: &User, - assignment: &Assignment, + assigned_function: &Function, event: &Event, ) -> Result<(), ApplicationError> { let message = build( &self.hostname, &user.name, &user.email, - &assignment.function, + &assigned_function, event, )?; self.transport.send(message).await?; diff --git a/web/templates/emails/notify_planned.html b/web/templates/emails/notify_planned.html index 3742becc..e71684a9 100644 --- a/web/templates/emails/notify_planned.html +++ b/web/templates/emails/notify_planned.html @@ -6,7 +6,7 @@
  • Name: {{ event.name }}
  • -
  • - Ort: {{ event.location.as_ref().unwrap().name }}
  • +
  • Ort: {{ event.location.as_ref().unwrap().name }}
  • Beginn: {{ event.start }}
  • Ende: {{ event.end }}
  • Kleidungsordnung: {{ event.clothing.name }}