Skip to content

Conversation

@carddev81
Copy link
Contributor

Description of the change

Implemented a time based attendance system that tracks actual attendance duration rather than presence/absence. This would allow administrators to record when residents arrive and leave classes. Ultimately this will provide more accurate attendance data for reporting and compliance purposes.

Screenshot(s)

image

@carddev81 carddev81 requested a review from a team as a code owner December 10, 2025 04:43
@carddev81 carddev81 requested review from corypride and removed request for a team December 10, 2025 04:43
@carddev81 carddev81 added HAS MIGRATION This PR has a migration added. Please collaborate with the author to resolve the ordering and removed HAS_MIGRATION labels Dec 10, 2025
var minutesAttended *int

if checkIn == "" && checkOut == "" {
if attendance.AttendanceStatus == models.Present || attendance.AttendanceStatus == models.Partial {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a record has attendance_status = 'partial' but no check-in/out times, System gives it full scheduled_minutes instead of 0.

Copy link
Contributor

@corypride corypride left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice implementation, it tests good, just a couple of small things and i think this is good to go.

Image
  • The "Time in Class" column shifts on Securebook Screen sizes.
Image
  • Maybe we should think about how frontend displays or handles this in-progress state. Say Waino was checked in at 7:00 PM and it's now later (say 8:30 PM), should the system be showing:
    "In-progress for 1.5 hours"?
    Or just show check-in time with empty check-out?

@carddev81 carddev81 force-pushed the carddev81/ticket_id506_timebasedtracking branch from 481d1b0 to fe856c5 Compare December 11, 2025 23:20
@carddev81 carddev81 requested a review from corypride December 11, 2025 23:22
@carddev81
Copy link
Contributor Author

Nice implementation, it tests good, just a couple of small things and i think this is good to go.

Image * The "Time in Class" column shifts on Securebook Screen sizes. Image * Maybe we should think about how frontend displays or handles this in-progress state. Say Waino was checked in at 7:00 PM and it's now later (say 8:30 PM), should the system be showing: "In-progress for 1.5 hours"? Or just show check-in time with empty check-out?

@corypride can you check this again on secure book screen size. I added keighan's changes to the code and changed things and made the screen real estate even more minimal. Please let me know.

@carddev81
Copy link
Contributor Author

Nice implementation, it tests good, just a couple of small things and i think this is good to go.

Image * The "Time in Class" column shifts on Securebook Screen sizes. Image * Maybe we should think about how frontend displays or handles this in-progress state. Say Waino was checked in at 7:00 PM and it's now later (say 8:30 PM), should the system be showing: "In-progress for 1.5 hours"? Or just show check-in time with empty check-out

Good question, not sure what the answer is or how we approach this? i'm good with empty check-out for now and then come back to enhance for any changes? @CK-7vn what is your opinion?

@carddev81 carddev81 requested a review from CK-7vn December 12, 2025 18:51
Copy link
Member

@CK-7vn CK-7vn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very trivial things, works great.

}

func (srv *Server) handleGetAttendanceRateForEvent(w http.ResponseWriter, r *http.Request, log sLog) error {
eventID, err := strconv.Atoi(r.PathValue("class_id"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you didn't change this, but...can you make the change while you're in here? eventID != class_id O.o

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, i'll make the change all the way down the chain

attendance.CheckOutAt = &checkOut
}

if minutesAttended != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can compact this if statement ot just attendance.MinutesAttended = minutesAttended

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to just attendance.MinutesAttended = minutesAttended ... nil is a possible value.

models.EnrollmentIncompleteTransfered,
}

csvRateCast := "COALESCE(pca.minutes_attended, pca.scheduled_minutes, 0)::numeric"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ratio calculation is in 4 different functions unless i'm missing something, GetProgramsFacilitiesStats, GetProgramsFacilityStats, GetProgramsOverviewTable, and GetProgramsCSVData, is there anyway we can just extract it out into a function?

  func buildPartialAttendanceRatioSQL(dialectName string) string {
      castMinutes := "COALESCE(pcea.minutes_attended, pcea.scheduled_minutes, 0)::numeric"
      if dialectName == "sqlite" {
          castMinutes = "CAST(COALESCE(pcea.minutes_attended, pcea.scheduled_minutes, 0) AS REAL)"
      }
      ratioExpr := fmt.Sprintf("%s / NULLIF(COALESCE(pcea.scheduled_minutes, pcea.minutes_attended, 0), 0)", castMinutes)
      return fmt.Sprintf("CASE WHEN %s < 1 THEN %s ELSE 1 END", ratioExpr, ratioExpr)
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call, i'll consolidate the code

@carddev81 carddev81 merged commit b7f4104 into main Jan 5, 2026
10 checks passed
@carddev81 carddev81 deleted the carddev81/ticket_id506_timebasedtracking branch January 5, 2026 16:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend frontend HAS MIGRATION This PR has a migration added. Please collaborate with the author to resolve the ordering HAS_MIGRATION

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants