add phep
All checks were successful
Deploy on Master Change / deploy (push) Successful in 1m12s

This commit is contained in:
2026-07-06 10:58:38 +07:00
parent 573ff17581
commit f5dce38e11
6 changed files with 398 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ package handlers
import (
"context"
"encoding/json"
"fmt"
"strconv"
"time"
@@ -542,3 +543,116 @@ func ListAttendanceShiftsHandler(db *gorm.DB) fiber.Handler {
return c.JSON(fiber.Map{"data": out, "date": date, "dayOfWeek": dayOfWeek})
}
}
// GET /api/classes/:rkId/leave-requests
func GetLeaveRequestsHandler(db *gorm.DB, qldtClient *qldt.Client) fiber.Handler {
return func(c *fiber.Ctx) error {
classRkID, _ := strconv.ParseInt(c.Params("rkId"), 10, 64)
courseID, _ := strconv.ParseInt(c.Query("courseId"), 10, 64)
date := c.Query("date", qldt.NowDateVN())
if courseID == 0 {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Missing courseId"})
}
token := GetQldtToken(db)
if token == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "QLDT_TOKEN chưa cấu hình"})
}
body, err := qldtClient.GetLeaveRequests(context.Background(), token, classRkID, courseID, date)
if err != nil {
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{"error": err.Error()})
}
var data any
if err := json.Unmarshal(body, &data); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to parse QLDT response"})
}
return c.JSON(data)
}
}
// POST /api/classes/:rkId/leave-requests/:leaveId/status
func UpdateLeaveStatusHandler(db *gorm.DB, qldtClient *qldt.Client) fiber.Handler {
return func(c *fiber.Ctx) error {
classRkID, _ := strconv.ParseInt(c.Params("rkId"), 10, 64)
leaveID, _ := strconv.ParseInt(c.Params("leaveId"), 10, 64)
var req struct {
Status string `json:"status"` // "Phê duyệt" or "Từ chối"
StudentRkID int64 `json:"studentRkId"`
Date string `json:"date"`
Period int `json:"period"`
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid body payload"})
}
if req.Status != "Phê duyệt" && req.Status != "Từ chối" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Trạng thái phê duyệt không hợp lệ"})
}
token := GetQldtToken(db)
if token == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "QLDT_TOKEN chưa cấu hình"})
}
// 1. Gửi lệnh cập nhật status qua QLDT Portal API
body, err := qldtClient.UpdateLeaveStatus(context.Background(), token, leaveID, req.Status)
if err != nil {
return c.Status(fiber.StatusBadGateway).JSON(fiber.Map{"error": err.Error(), "body": string(body)})
}
// 2. Nếu status là "Phê duyệt", tự động cập nhật điểm danh trong hệ thống của chúng ta thành "Nghỉ có phép"
if req.Status == "Phê duyệt" {
if req.StudentRkID == 0 || req.Date == "" || req.Period == 0 {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Thiếu thông tin cập nhật điểm danh (studentRkId, date, period)"})
}
dayOfWeek, err := scheduleDayFromDate(req.Date)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Ngày không hợp lệ"})
}
sched, err := resolveScheduleForPeriod(db, classRkID, dayOfWeek, req.Period)
if err != nil || sched == nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Không tìm thấy lịch học cho ca này"})
}
// Cập nhật hoặc Tạo mới AttendanceResult
var row models.AttendanceResult
errFind := db.Where("class_rk_id = ? AND session_date = ? AND period = ? AND student_rk_id = ?",
classRkID, req.Date, req.Period, req.StudentRkID).First(&row).Error
if errFind == nil {
// Cập nhật hàng có sẵn
row.Status = 1 // Nghỉ có phép
row.StatusLabel = "Nghỉ có phép"
row.StatusEditedByTeacher = true
if err := db.Save(&row).Error; err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Lỗi lưu điểm danh: " + err.Error()})
}
} else if errFind == gorm.ErrRecordNotFound {
// Tạo mới hàng
row = models.AttendanceResult{
ClassRkID: classRkID,
SessionDate: req.Date,
Period: req.Period,
StudentRkID: req.StudentRkID,
Status: 1,
StatusLabel: "Nghỉ có phép",
StatusEditedByTeacher: true,
}
if err := db.Create(&row).Error; err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Lỗi tạo điểm danh: " + err.Error()})
}
} else {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": errFind.Error()})
}
}
return c.JSON(fiber.Map{"ok": true, "message": "Cập nhật đơn xin nghỉ thành công!"})
}
}