import { apiRequestData } from "./http"; export type AttendanceExemptionReason = | "leave" | "travel" | "holiday" | "weekend" | "policy_disabled"; export type AttendanceStatus = | "normal" | "late" | "early_leave" | "late_early_leave" | "pending_clock_out" | "missed" | "leave" | "travel" | "holiday" | "weekend"; export type AttendanceRecordItem = { id: string | null; employeeId: string; workDate: string; clockInAt: string | null; clockOutAt: string | null; workMinutes: number | null; isLate: boolean; lateMinutes: number; isEarlyLeave: boolean; earlyMinutes: number; note: string | null; source: "web" | "mobile" | "admin" | null; updatedAt: string | null; }; export type AttendanceTodayResponse = { workDate: string; needClockIn: boolean; exemptionReason: AttendanceExemptionReason | null; item: AttendanceRecordItem | null; }; export type AttendanceMonthItem = AttendanceRecordItem & { attendanceStatus: AttendanceStatus; needClockIn: boolean; exemptionReason: AttendanceExemptionReason | null; }; export type AttendanceMonthSummary = { totalWorkDays: number; clockedDays: number; lateDays: number; earlyLeaveDays: number; missedDays: number; totalWorkMinutes: number; }; export type AttendanceMonthResponse = { year: number; month: number; summary: AttendanceMonthSummary; items: AttendanceMonthItem[]; }; export type AttendanceTeamItem = { employeeId: string; employeeName: string; employeeNo: string; title: string; departmentId: string | null; departmentName: string | null; attendanceStatus: AttendanceStatus; needClockIn: boolean; exemptionReason: AttendanceExemptionReason | null; clockInAt: string | null; clockOutAt: string | null; workMinutes: number | null; note: string | null; source: "web" | "mobile" | "admin" | null; }; export type AttendancePolicy = { id: string | null; workStartTime: string; workEndTime: string; lunchStartTime: string; lunchEndTime: string; lateToleranceMinutes: number; enabled: boolean; createdAt: string | null; updatedAt: string | null; updatedBy: string | null; }; export async function clockInAttendance(note?: string | null) { return apiRequestData<{ item: AttendanceRecordItem }>("/api/attendance/clock-in", { method: "POST", body: JSON.stringify(note ? { note } : {}), }); } export async function clockOutAttendance(note?: string | null) { return apiRequestData<{ item: AttendanceRecordItem }>("/api/attendance/clock-out", { method: "POST", body: JSON.stringify(note ? { note } : {}), }); } export async function fetchMyTodayAttendance() { return apiRequestData("/api/attendance/me/today"); } export async function fetchMyMonthAttendance(params?: { year?: number; month?: number }) { const search = new URLSearchParams(); if (params?.year) { search.set("year", String(params.year)); } if (params?.month) { search.set("month", String(params.month)); } const query = search.toString(); return apiRequestData(`/api/attendance/me/month${query ? `?${query}` : ""}`); } export async function fetchTeamAttendance(params?: { date?: string; departmentId?: string }) { const search = new URLSearchParams(); if (params?.date) { search.set("date", params.date); } if (params?.departmentId) { search.set("departmentId", params.departmentId); } const query = search.toString(); return apiRequestData<{ date: string; items: AttendanceTeamItem[] }>(`/api/attendance/team${query ? `?${query}` : ""}`); } export async function fetchAttendancePolicy() { return apiRequestData<{ item: AttendancePolicy }>("/api/attendance/policy"); } export async function updateAttendancePolicy(payload: { workStartTime: string; workEndTime: string; lunchStartTime: string; lunchEndTime: string; lateToleranceMinutes: number; enabled?: boolean; }) { return apiRequestData<{ item: AttendancePolicy }>("/api/attendance/policy", { method: "PUT", body: JSON.stringify(payload), }); } export async function adminBackfillAttendance(payload: { employeeId: string; workDate: string; clockInAt?: string | null; clockOutAt?: string | null; note?: string | null; }) { return apiRequestData<{ item: AttendanceRecordItem }>("/api/attendance/admin/backfill", { method: "POST", body: JSON.stringify(payload), }); }