From 18cf23fc0f71fe06c4d55dc891ba3f00590c01a7 Mon Sep 17 00:00:00 2001 From: Tejas Date: Wed, 11 Jun 2025 18:43:21 +0530 Subject: [PATCH] present and absent count --- Cargo.lock | 29 +++++--- Cargo.toml | 1 + src/graphql/queries/attendance_queries.rs | 2 + src/graphql/queries/member_queries.rs | 86 +++++++++++++++++++++++ src/main.rs | 10 ++- src/models/attendance.rs | 2 + 6 files changed, 118 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c00b3f1..48518bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -69,6 +69,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + [[package]] name = "arraydeque" version = "0.5.1" @@ -83,9 +89,9 @@ checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" [[package]] name = "async-graphql" -version = "7.0.15" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfff2b17d272a5e3e201feda444e2c24b011fa722951268d1bd8b9b5bc6dc449" +checksum = "036618f842229ba0b89652ffe425f96c7c16a49f7e3cb23b56fca7f61fd74980" dependencies = [ "async-graphql-derive", "async-graphql-parser", @@ -117,9 +123,9 @@ dependencies = [ [[package]] name = "async-graphql-axum" -version = "7.0.15" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf2882c816094fef6e39d381b8e9b710e5943e7bdef5198496441d5083164fa" +checksum = "8725874ecfbf399e071150b8619c4071d7b2b7a2f117e173dddef53c6bdb6bb1" dependencies = [ "async-graphql", "axum", @@ -134,9 +140,9 @@ dependencies = [ [[package]] name = "async-graphql-derive" -version = "7.0.15" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e5d0c6697def2f79ccbd972fb106b633173a6066e430b480e1ff9376a7561a" +checksum = "fd45deb3dbe5da5cdb8d6a670a7736d735ba65b455328440f236dfb113727a3d" dependencies = [ "Inflector", "async-graphql-parser", @@ -151,9 +157,9 @@ dependencies = [ [[package]] name = "async-graphql-parser" -version = "7.0.15" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8531ee6d292c26df31c18c565ff22371e7bdfffe7f5e62b69537db0b8fd554dc" +checksum = "60b7607e59424a35dadbc085b0d513aa54ec28160ee640cf79ec3b634eba66d3" dependencies = [ "async-graphql-value", "pest", @@ -163,9 +169,9 @@ dependencies = [ [[package]] name = "async-graphql-value" -version = "7.0.15" +version = "7.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "741110dda927420a28fbc1c310543d3416f789a6ba96859c2c265843a0a96887" +checksum = "34ecdaff7c9cffa3614a9f9999bf9ee4c3078fe3ce4d6a6e161736b56febf2de" dependencies = [ "bytes", "indexmap", @@ -2032,6 +2038,7 @@ dependencies = [ name = "root" version = "0.1.0" dependencies = [ + "anyhow", "async-graphql", "async-graphql-axum", "axum", diff --git a/Cargo.toml b/Cargo.toml index 273da9f..f598ffb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,4 @@ tracing = "0.1.41" tracing-subscriber = { version = "0.3.19", features = ["env-filter", "time", "fmt", "std"] } dotenv = "0.15.0" time = { version = "0.3.37", features = ["formatting"] } +anyhow = "1.0.98" diff --git a/src/graphql/queries/attendance_queries.rs b/src/graphql/queries/attendance_queries.rs index 2050051..1af14af 100644 --- a/src/graphql/queries/attendance_queries.rs +++ b/src/graphql/queries/attendance_queries.rs @@ -41,4 +41,6 @@ impl AttendanceQueries { Ok(records) } + + } diff --git a/src/graphql/queries/member_queries.rs b/src/graphql/queries/member_queries.rs index efa2ecf..6acffbb 100644 --- a/src/graphql/queries/member_queries.rs +++ b/src/graphql/queries/member_queries.rs @@ -1,6 +1,8 @@ use async_graphql::{ComplexObject, Context, Object, Result}; use sqlx::PgPool; use std::sync::Arc; +use chrono::NaiveDate; + use crate::models::{ attendance::{AttendanceInfo, AttendanceSummaryInfo}, @@ -106,5 +108,89 @@ impl Member { .fetch_all(pool.as_ref()) .await .unwrap_or_default() + + + } + + async fn present_count_by_date( + &self, + ctx: &Context<'_>, + start_date: NaiveDate, + end_date:NaiveDate, + ) -> Result{ + + if end_date < start_date { + return Err("end_date must be >= start_date".into()); + } + + let pool = ctx.data::>().expect("Pool must be in context."); + + let records : i64 = sqlx::query_scalar( + " + SELECT COUNT(att.is_present) + FROM attendance att + INNER JOIN member m ON att.member_id = m.member_id + WHERE att.member_id = $3 + AND att.is_present = true + AND att.date BETWEEN $1 AND $2" + ) + .bind(start_date) + .bind(end_date) + .bind(self.member_id) + .fetch_one(pool.as_ref()) + .await?; + + Ok(records) + + } + + async fn absent_count_by_date( + &self, + ctx: &Context<'_>, + start_date: NaiveDate, + end_date:NaiveDate, + ) -> Result{ + + if end_date < start_date { + return Err("end_date must be >= start_date".into()); + } + + let pool = ctx.data::>().expect("Pool must be in context."); + + let working_days : i64 = sqlx::query_scalar( + " + SELECT COUNT(*) AS working_days + FROM ( + SELECT date + FROM attendance + where date between $1 and $2 GROUP BY date + HAVING BOOL_or(is_present = true) + ) AS working_dates; + " + ) + + .bind(start_date) + .bind(end_date) + .bind(self.member_id) + .fetch_one(pool.as_ref()) + .await?; + + let present : i64 = sqlx::query_scalar( + " + SELECT COUNT(att.is_present) + FROM attendance att + INNER JOIN member m ON att.member_id = m.member_id + WHERE att.member_id = $3 + AND att.is_present = true + AND att.date BETWEEN $1 AND $2" + ) + .bind(start_date) + .bind(end_date) + .bind(self.member_id) + .fetch_one(pool.as_ref()) + .await?; + + Ok(working_days-present) + } } diff --git a/src/main.rs b/src/main.rs index 17b0611..ef4ae68 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,9 @@ pub mod graphql; pub mod models; pub mod routes; +use dotenv::dotenv; + + /// Handles all over environment variables in one place. // TODO: Replace with `Config.rs` crate. struct Config { @@ -39,6 +42,11 @@ impl Config { #[tokio::main] async fn main() { + dotenv().ok(); + + // Fetch the DATABASE_URL env var + + let config = Config::from_env(); setup_tracing(&config.env); @@ -53,7 +61,7 @@ async fn main() { let router = setup_router(schema, cors, config.env == "development"); info!("Starting Root..."); - let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", config.port)) + let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}",config.port)) .await .unwrap(); axum::serve(listener, router).await.unwrap(); diff --git a/src/models/attendance.rs b/src/models/attendance.rs index 9efc9dc..0bcc846 100644 --- a/src/models/attendance.rs +++ b/src/models/attendance.rs @@ -58,3 +58,5 @@ pub struct AttendanceWithMember { pub year: i32, pub group_id: i32, } + +