-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2ec7f6b
commit b38f2fa
Showing
15 changed files
with
413 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CREATE TABLE email_templates ( | ||
id BIGINT PRIMARY KEY, | ||
organisation_id BIGINT NOT NULL, | ||
name TEXT NOT NULL, | ||
template TEXT NOT NULL, | ||
CONSTRAINT FK_email_templates_organisations | ||
FOREIGN KEY(organisation_id) | ||
REFERENCES organisations(id) | ||
ON DELETE CASCADE | ||
ON UPDATE CASCADE, | ||
UNIQUE (organisation_id, name) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
CREATE TYPE offer_status AS ENUM ('Draft', 'Sent', 'Accepted', 'Declined'); | ||
|
||
CREATE TABLE offers ( | ||
id BIGINT PRIMARY KEY, | ||
campaign_id BIGINT NOT NULL, | ||
application_id BIGINT NOT NULL, | ||
email_template_id BIGINT NOT NULL, | ||
role_id BIGINT NOT NULL, | ||
expiry TIMESTAMPTZ NOT NULL, | ||
status offer_status NOT NULL DEFAULT 'Draft', | ||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
CONSTRAINT FK_offers_campaigns | ||
FOREIGN KEY(campaign_id) | ||
REFERENCES campaigns(id) | ||
ON DELETE CASCADE | ||
ON UPDATE CASCADE, | ||
CONSTRAINT FK_offers_applications | ||
FOREIGN KEY(application_id) | ||
REFERENCES applications(id) | ||
ON DELETE CASCADE | ||
ON UPDATE CASCADE, | ||
CONSTRAINT FK_offers_email_templates | ||
FOREIGN KEY(email_template_id) | ||
REFERENCES email_templates(id) | ||
ON DELETE CASCADE | ||
ON UPDATE CASCADE, | ||
CONSTRAINT FK_offers_roles | ||
FOREIGN KEY(role_id) | ||
REFERENCES campaign_roles(id) | ||
ON DELETE CASCADE | ||
ON UPDATE CASCADE | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,4 +26,4 @@ rust-s3 = "0.34.0" | |
rs-snowflake = "0.6" | ||
jsonwebtoken = "9.1" | ||
dotenvy = "0.15" | ||
|
||
handlebars = "6.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use axum::extract::{Path, State, Json}; | ||
use axum::http::StatusCode; | ||
use axum::response::IntoResponse; | ||
use crate::models::app::AppState; | ||
use crate::models::auth::EmailTemplateAdmin; | ||
use crate::models::email_template::EmailTemplate; | ||
use crate::models::error::ChaosError; | ||
use crate::models::transaction::DBTransaction; | ||
|
||
pub struct EmailTemplateHandler; | ||
impl EmailTemplateHandler { | ||
pub async fn get( | ||
mut transaction: DBTransaction<'_>, | ||
Path(id): Path<i64>, | ||
_user: EmailTemplateAdmin, | ||
) -> Result<impl IntoResponse, ChaosError> { | ||
let email_template = EmailTemplate::get(id, &mut transaction.tx).await?; | ||
|
||
Ok((StatusCode::OK, Json(email_template))) | ||
} | ||
|
||
pub async fn update( | ||
_user: EmailTemplateAdmin, | ||
Path(id): Path<i64>, | ||
State(state): State<AppState>, | ||
Json(request_body): Json<EmailTemplate> | ||
) -> Result<impl IntoResponse, ChaosError> { | ||
EmailTemplate::update(id, request_body.name, request_body.template, &state.db).await?; | ||
|
||
Ok((StatusCode::OK, "Successfully updated email template")) | ||
} | ||
|
||
pub async fn delete( | ||
_user: EmailTemplateAdmin, | ||
Path(id): Path<i64>, | ||
State(state): State<AppState>, | ||
) -> Result<impl IntoResponse, ChaosError> { | ||
EmailTemplate::delete(id, &state.db).await?; | ||
|
||
Ok((StatusCode::OK, "Successfully delete email template")) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ pub mod question; | |
pub mod rating; | ||
pub mod role; | ||
pub mod user; | ||
pub mod email_template; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use std::collections::HashMap; | ||
use std::ops::DerefMut; | ||
use chrono::{DateTime, Local, Utc}; | ||
use handlebars::Handlebars; | ||
use serde::{Deserialize, Serialize}; | ||
use snowflake::SnowflakeIdGenerator; | ||
use sqlx::{Pool, Postgres, Transaction}; | ||
use crate::models::application::Application; | ||
use crate::models::campaign::Campaign; | ||
use crate::models::error::ChaosError; | ||
|
||
/// Email templates to update applicants | ||
/// Supported tags: | ||
/// - `name` | ||
/// - `role` | ||
/// - `organisation_name` | ||
/// - `expiry_date` | ||
/// - `campaign_name` | ||
#[derive(Deserialize, Serialize)] | ||
pub struct EmailTemplate { | ||
pub id: i64, | ||
pub organisation_id: i64, | ||
pub name: String, | ||
pub template: String, | ||
} | ||
|
||
impl EmailTemplate { | ||
pub async fn get(id: i64, transaction: &mut Transaction<'_, Postgres>) -> Result<EmailTemplate, ChaosError> { | ||
let template = sqlx::query_as!( | ||
EmailTemplate, | ||
"SELECT * FROM email_templates WHERE id = $1", | ||
id | ||
) | ||
.fetch_one(transaction.deref_mut()).await?; | ||
|
||
Ok(template) | ||
} | ||
|
||
pub async fn get_all_by_organisation(organisation_id: i64, pool: &Pool<Postgres>) -> Result<Vec<EmailTemplate>, ChaosError> { | ||
let templates = sqlx::query_as!( | ||
EmailTemplate, | ||
"SELECT * FROM email_templates WHERE organisation_id = $1", | ||
organisation_id | ||
) | ||
.fetch_all(pool).await?; | ||
|
||
Ok(templates) | ||
} | ||
|
||
pub async fn update(id: i64, name: String, template: String, pool: &Pool<Postgres>) -> Result<(), ChaosError> { | ||
let _ = sqlx::query!( | ||
" | ||
UPDATE email_templates SET name = $2, template = $3 WHERE id = $1 RETURNING id | ||
", | ||
id, name, template | ||
) | ||
.fetch_one(pool).await?; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub async fn delete(id: i64, pool: &Pool<Postgres>) -> Result<(), ChaosError> { | ||
let _ = sqlx::query!( | ||
"DELETE FROM email_templates WHERE id = $1 RETURNING id", | ||
id | ||
).fetch_one(pool).await?; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub async fn generate_email( | ||
name: String, | ||
role: String, | ||
organisation_name: String, | ||
campaign_name: String, | ||
expiry_date: DateTime<Utc>, | ||
email_template_id: i64, | ||
transaction: &mut Transaction<'_, Postgres>, | ||
) -> Result<String, ChaosError> { | ||
let template = EmailTemplate::get(email_template_id, transaction).await?; | ||
|
||
let mut handlebars = Handlebars::new(); | ||
handlebars.register_template_string("template", template.template)?; | ||
|
||
let mut data = HashMap::new(); | ||
data.insert("name", name); | ||
data.insert("role", role); | ||
data.insert("organisation_name", organisation_name); | ||
data.insert("campaign_name", campaign_name); | ||
data.insert("expiry_date", expiry_date.with_timezone(&Local).format("%d/%m/%Y %H:%M").to_string()); | ||
|
||
let final_string = handlebars.render("template", &data)?; | ||
|
||
Ok(final_string) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,5 @@ pub mod role; | |
pub mod storage; | ||
pub mod transaction; | ||
pub mod user; | ||
pub mod email_template; | ||
pub mod offer; |
Oops, something went wrong.