import { apiRequestData } from "./http"; export type LeaveSession = "am" | "pm"; export type LeaveRequestStatus = "draft" | "reviewing" | "approved" | "rejected" | "cancelled"; export type LeaveType = { id: string; code: string; name: string; description: string | null; enabled: boolean; requiresAttachment: boolean; attachmentMimeTypes: string[]; sortOrder: number; policy: { id: string; annualQuotaDays: number; enabled: boolean; description: string | null; } | null; createdAt: string | null; updatedAt: string | null; }; export type LeaveBalanceItem = { leaveType: LeaveType; policy: { id: string; annualQuotaDays: number; enabled: boolean; description: string | null; }; granted: number; adjusted: number; reserved: number; used: number; available: number; periodStart: string | null; periodEnd: string | null; }; export type LeaveRequestItem = { id: string; ownerId: string; departmentId: string; status: LeaveRequestStatus; startDate: string; endDate: string; startSession: LeaveSession; endSession: LeaveSession; requestedDays: number; reason: string | null; attachment: { originalName: string | null; mimeType: string | null; } | null; leaveType: { id: string; code: string; name: string; requiresAttachment: boolean; attachmentMimeTypes: string[]; } | null; owner: { id: string; employeeNo: string; name: string; } | null; createdAt: string | null; updatedAt: string | null; }; export type LeaveRequestListResponse = { page: number; pageSize: number; total: number; scope: "own" | "all"; items: LeaveRequestItem[]; }; export type LeaveBalanceResponse = { employeeId: string; items: LeaveBalanceItem[]; }; export type LeaveWorkingDaysPreview = { requestedDays: number; naturalRequestedDays: number; holidayDayCount: number; weekendDayCount: number; adjustedWorkdayCount: number; calendarApplied: boolean; }; export type LeaveListQuery = { status?: LeaveRequestStatus; scope?: "own" | "all"; page?: number; pageSize?: number; dateFrom?: string; dateTo?: string; departmentId?: string; }; function toQueryString(query: Record) { const params = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { if (value == null || value === "") { continue; } params.set(key, String(value)); } const encoded = params.toString(); return encoded ? `?${encoded}` : ""; } export async function fetchLeaveTypes(params?: { enabled?: boolean }) { return apiRequestData<{ items: LeaveType[] }>( `/api/leave-types${toQueryString({ enabled: params?.enabled == null ? undefined : String(params.enabled) })}`, ); } export async function createLeaveType(payload: { code: string; name: string; description?: string | null; enabled?: boolean; requiresAttachment?: boolean; attachmentMimeTypes?: string[]; sortOrder?: number; annualQuotaDays: number; policyDescription?: string | null; }) { return apiRequestData("/api/leave-types", { method: "POST", body: JSON.stringify(payload), }); } export async function patchLeaveType( leaveTypeId: string, payload: Partial<{ code: string; name: string; description: string | null; enabled: boolean; requiresAttachment: boolean; attachmentMimeTypes: string[]; sortOrder: number; annualQuotaDays: number; policyDescription: string | null; }>, ) { return apiRequestData(`/api/leave-types/${leaveTypeId}`, { method: "PATCH", body: JSON.stringify(payload), }); } export async function fetchLeaveBalances(employeeId?: string) { return apiRequestData( `/api/leave-balances${toQueryString({ employeeId })}`, ); } export async function fetchLeaveRequests(query: LeaveListQuery = {}) { return apiRequestData( `/api/leave-requests${toQueryString(query as Record)}`, ); } export async function fetchLeaveRequestDetail(leaveRequestId: string) { return apiRequestData(`/api/leave-requests/${leaveRequestId}`); } export async function fetchLeaveWorkingDaysPreview(query: { startDate: string; endDate: string; startSession: LeaveSession; endSession: LeaveSession; }) { return apiRequestData( `/api/leave-requests/working-days${toQueryString(query)}`, ); } export async function createLeaveRequest(payload: { leaveTypeId: string; startDate: string; endDate: string; startSession: LeaveSession; endSession: LeaveSession; reason?: string; file?: File | null; }) { const formData = new FormData(); formData.append("leaveTypeId", payload.leaveTypeId); formData.append("startDate", payload.startDate); formData.append("endDate", payload.endDate); formData.append("startSession", payload.startSession); formData.append("endSession", payload.endSession); if (payload.reason?.trim()) { formData.append("reason", payload.reason.trim()); } if (payload.file) { formData.append("file", payload.file); } return apiRequestData("/api/leave-requests", { method: "POST", body: formData, }); } export async function submitLeaveRequest(leaveRequestId: string) { return apiRequestData>(`/api/leave-requests/${leaveRequestId}/submit`, { method: "POST", body: JSON.stringify({}), }); } export async function patchLeaveRequest( leaveRequestId: string, payload: { leaveTypeId: string; startDate: string; endDate: string; startSession: LeaveSession; endSession: LeaveSession; reason?: string; file?: File | null; }, ) { const formData = new FormData(); formData.append("leaveTypeId", payload.leaveTypeId); formData.append("startDate", payload.startDate); formData.append("endDate", payload.endDate); formData.append("startSession", payload.startSession); formData.append("endSession", payload.endSession); if (payload.reason?.trim()) { formData.append("reason", payload.reason.trim()); } if (payload.file) { formData.append("file", payload.file); } return apiRequestData(`/api/leave-requests/${leaveRequestId}`, { method: "PATCH", body: formData, }); } export async function withdrawLeaveRequest(leaveRequestId: string, comment?: string) { return apiRequestData>(`/api/leave-requests/${leaveRequestId}/withdraw`, { method: "POST", body: JSON.stringify({ comment }), }); }