From a0e15e5bfd2e5b8d90d28281cd65263461ba5d28 Mon Sep 17 00:00:00 2001 From: Araozu Date: Wed, 30 Aug 2023 08:55:05 -0500 Subject: [PATCH] [BE][Certs] Create new register --- backend/Cargo.lock | 81 ++++++++++++++++++++++++-- backend/Cargo.toml | 1 + backend/sql/schema.sql | 14 +++++ backend/src/controller/register/mod.rs | 9 +++ backend/src/model/course.rs | 16 +++++ backend/src/model/register.rs | 78 ++++++++++++++++++++++++- 6 files changed, 192 insertions(+), 7 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 749534a..9432a5c 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -44,6 +44,21 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -102,6 +117,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" name = "backend" version = "0.1.0" dependencies = [ + "chrono", "dotenvy", "once_cell", "reqwest", @@ -200,6 +216,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56b4c72906975ca04becb8a30e102dfecddd0c06181e3e95ddc444be28881f8" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "time 0.1.45", + "wasm-bindgen", + "windows-targets", +] + [[package]] name = "const-oid" version = "0.9.5" @@ -213,7 +244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ "percent-encoding", - "time", + "time 0.3.27", "version_check", ] @@ -596,7 +627,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -774,6 +805,29 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.4.0" @@ -973,7 +1027,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys", ] @@ -1529,7 +1583,7 @@ dependencies = [ "serde_json", "state", "tempfile", - "time", + "time 0.3.27", "tokio", "tokio-stream", "tokio-util", @@ -1577,7 +1631,7 @@ dependencies = [ "smallvec", "stable-pattern", "state", - "time", + "time 0.3.27", "tokio", "uncased", "uuid", @@ -2189,6 +2243,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + [[package]] name = "time" version = "0.3.27" @@ -2522,6 +2587,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 1ee0d99..d32e31d 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -12,3 +12,4 @@ sqlx = { version = "0.7.1", features = [ "runtime-tokio", "tls-rustls", "mysql", once_cell = "1.18.0" dotenvy = "0.15.7" serde = "1.0.188" +chrono = "0.4.27" diff --git a/backend/sql/schema.sql b/backend/sql/schema.sql index 4f87e96..50c3523 100644 --- a/backend/sql/schema.sql +++ b/backend/sql/schema.sql @@ -18,6 +18,20 @@ CREATE TABLE course ( course_has_custom_label BOOLEAN NOT NULL ); +CREATE TABLE register ( + register_id INTEGER PRIMARY KEY AUTO_INCREMENT, + register_code INTEGER NOT NULL, + register_creation_date DATETIME NOT NULL, + register_display_date DATETIME NOT NULL, + register_custom_label VARCHAR(100) NOT NULL, + register_is_preview BOOLEAN NOT NULL, + register_person_id INTEGER NOT NULL, + register_course_id INTEGER NOT NULL, + + FOREIGN KEY (register_person_id) REFERENCES person (person_id), + FOREIGN KEY (register_course_id) REFERENCES course (course_id) +); + -- Course list INSERT INTO course (course_name, course_display_name, course_days_amount, course_has_custom_label) VALUES diff --git a/backend/src/controller/register/mod.rs b/backend/src/controller/register/mod.rs index 744030e..af85167 100644 --- a/backend/src/controller/register/mod.rs +++ b/backend/src/controller/register/mod.rs @@ -9,6 +9,15 @@ pub fn options() -> Status { #[post("/register/batch", format = "json", data = "")] pub async fn insert_all(data: Json>) -> Status { + for register_create in data.iter() { + let res = register_create.create().await; + + if let Err(err) = res { + eprintln!("Error creating register: {}", err); + return Status::InternalServerError; + } + } + Status::Ok } diff --git a/backend/src/model/course.rs b/backend/src/model/course.rs index e7f2154..227ed47 100644 --- a/backend/src/model/course.rs +++ b/backend/src/model/course.rs @@ -44,4 +44,20 @@ impl Course { Ok(results) } + + pub async fn get_course_name(course_id: i32) -> Option { + let db = db(); + + let res = sqlx::query!( + "SELECT course_name FROM course WHERE course_id = ?", + course_id + ) + .fetch_one(db) + .await; + + match res { + Ok(data) => Some(data.course_name), + Err(_) => None, + } + } } diff --git a/backend/src/model/register.rs b/backend/src/model/register.rs index ea94260..21e18bc 100644 --- a/backend/src/model/register.rs +++ b/backend/src/model/register.rs @@ -1,6 +1,13 @@ -use rocket::serde::{Deserialize, Serialize}; +use rocket::{ + form::validate::Contains, + serde::{Deserialize, Serialize}, +}; -#[derive(Serialize, Deserialize, Clone)] +use crate::db; + +use super::course::Course; + +#[derive(Serialize, Deserialize, Clone, Debug)] #[serde(crate = "rocket::serde")] /// Represents a single register send by the frontend /// to create a new register in the database @@ -35,3 +42,70 @@ pub struct Register { /// Foreign key to the course table pub register_course_id: i32, } + +impl RegisterCreate { + pub async fn create(&self) -> Result<(), sqlx::Error> { + let db = db(); + + let next_register_code = Self::get_next_register_code(self.course_id).await?; + + // Current date in YYYY-MM-DD format + let current_date = chrono::Local::now().format("%Y-%m-%d").to_string(); + + let _ = sqlx::query!( + "INSERT INTO register ( + register_code, + register_creation_date, + register_display_date, + register_custom_label, + register_is_preview, + register_person_id, + register_course_id + ) VALUES (?, ?, ?, ?, ?, ?, ?)", + next_register_code, + current_date, + self.date, + "", + false, + self.person_id, + self.course_id + ) + .execute(db) + .await?; + + Ok(()) + } + + async fn get_next_register_code(course_id: i32) -> Result { + let db = db(); + + let course_name = Course::get_course_name(course_id).await; + + // All matpel certs share codes + let new_max = if course_name.contains("Matpel") { + let res = sqlx::query!( + "SELECT MAX(register_code) AS max FROM register + WHERE register_course_id IN + (SELECT course_id FROM course WHERE course_name LIKE 'Matpel%')", + ) + .fetch_one(db) + .await?; + + // If there are no registers, the new code will start from 50, as per the requirements + res.max.unwrap_or(50) + 1 + } else { + let res = sqlx::query!( + "SELECT MAX(register_code) AS max FROM register + WHERE register_course_id = ?", + course_id + ) + .fetch_one(db) + .await?; + + // If there are no registers, the new code will start from 50, as per the requirements + res.max.unwrap_or(50) + 1 + }; + + Ok(new_max) + } +}