Skip to content

Commit

Permalink
feat: Add attendanceByDate query.
Browse files Browse the repository at this point in the history
Supports fetching attendance for all members for a given date.

Fixes #72
  • Loading branch information
chimnayajith committed Feb 28, 2025
1 parent 35a3115 commit ebcc703
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
32 changes: 32 additions & 0 deletions docs/attendance.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@ struct AttendanceSummary {

## Queries

### Get Attendance
Retrieve attendance records by member ID or date.

```graphql
# Get attendance by member ID
query {
attendance(memberId: 1) {
attendanceId
date
isPresent
timeIn
timeOut
}
}
```

Get all attendance for a specific date

```graphql
query {
attendanceByDate(date: "2025-02-27") {
attendanceId
memberId
name
year
isPresent
timeIn
timeOut
}
}
```

### Mark Attendance
Record a member's attendance for the day.

Expand Down
31 changes: 28 additions & 3 deletions src/graphql/queries/attendance_queries.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::sync::Arc;

use crate::models::{
attendance::{Attendance, AttendanceWithMember},
member::Member,
};
use async_graphql::{Context, Object, Result};
use chrono::NaiveDate;
use sqlx::PgPool;

use crate::models::{attendance::Attendance, member::Member};

/// Sub-query for the [`Attendance`] table. The queries are:
/// * attendance - get a specific member's attendance details using their member_id, roll_no or discord_id
/// * attendance - get a specific member's attendance details using their member_id, roll_no or discord_id, or by date for all members.
#[derive(Default)]
pub struct AttendanceQueries;

Expand Down Expand Up @@ -66,4 +69,26 @@ impl AttendanceQueries {

Ok(attendance_query)
}

// Query to get attendance by date
async fn attendance_by_date(
&self,
ctx: &Context<'_>,
date: NaiveDate,
) -> Result<Vec<AttendanceWithMember>> {
let pool = ctx.data::<Arc<PgPool>>().expect("Pool must be in context.");

let records = sqlx::query_as::<_, AttendanceWithMember>(
"SELECT a.attendance_id, a.member_id, a.date, a.is_present,
a.time_in, a.time_out, m.name, m.year
FROM Attendance a
JOIN Member m ON a.member_id = m.member_id
WHERE a.date = $1",
)
.bind(date)
.fetch_all(pool.as_ref())
.await?;

Ok(records)
}
}
14 changes: 14 additions & 0 deletions src/models/attendance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,17 @@ pub struct MarkAttendanceInput {
pub date: NaiveDate,
pub hmac_signature: String,
}

/// This struct combines attendance data with member name for queries that need both.
/// It joins the Attendance table with Member to include the member's name.
#[derive(SimpleObject, FromRow)]
pub struct AttendanceWithMember {
pub attendance_id: i32,
pub member_id: i32,
pub date: NaiveDate,
pub is_present: bool,
pub time_in: Option<NaiveTime>,
pub time_out: Option<NaiveTime>,
pub name: String,
pub year: i32,
}

0 comments on commit ebcc703

Please sign in to comment.