716 行
20 KiB
TypeScript
716 行
20 KiB
TypeScript
import { apiRequestBlob, apiRequestData, type ApiBlobResponse } from "./http";
|
|
|
|
export type EmployeeStatus = "active" | "archived";
|
|
export type EmployeeEmploymentStatus = "onboarding" | "probation" | "active" | "offboarding" | "inactive";
|
|
export type EmployeeContractType = "labor" | "nda" | "non_compete" | "internship";
|
|
export type EmployeeContractStatus = "active" | "expired" | "terminated";
|
|
export type EmployeeTrainingType = "internal" | "external" | "online";
|
|
export type EmployeeTrainingStatus = "planned" | "in_progress" | "completed" | "cancelled";
|
|
export type EmployeeCertificateStatus = "valid" | "expired";
|
|
export type WecomDirectorySyncOperation = "create" | "update" | "disable";
|
|
export type WecomDirectorySyncStatus = "running" | "success" | "failed" | "skipped";
|
|
export type WecomDirectoryStateStatus = "unbound" | "bound" | "synced" | "sync_success" | "sync_skipped" | "sync_failed";
|
|
|
|
export type WecomDirectorySyncRun = {
|
|
id: string;
|
|
employeeId: string;
|
|
externalUserId: string | null;
|
|
operation: WecomDirectorySyncOperation;
|
|
status: WecomDirectorySyncStatus;
|
|
attempts: number;
|
|
errorCode: string | null;
|
|
errorMessage: string | null;
|
|
responseSummary: Record<string, unknown> | null;
|
|
triggeredBy: string | null;
|
|
createdAt: string | null;
|
|
updatedAt: string | null;
|
|
};
|
|
|
|
export type WecomDirectoryState = {
|
|
status: WecomDirectoryStateStatus;
|
|
externalUserId: string | null;
|
|
bound: boolean;
|
|
latestSync: WecomDirectorySyncRun | null;
|
|
};
|
|
|
|
export type WecomHrMasterSyncMode = "dry_run" | "apply";
|
|
export type WecomHrMasterSyncRunStatus = "running" | "success" | "partial" | "failed" | "skipped";
|
|
export type WecomHrMasterSyncItemStatus = "planned" | "success" | "skipped" | "conflict" | "failed";
|
|
|
|
export type WecomHrMasterSyncItem = {
|
|
id: string;
|
|
runId: string;
|
|
employeeId: string | null;
|
|
externalUserId: string;
|
|
action: "create" | "update" | "noop" | "skip" | "conflict" | "failed";
|
|
status: WecomHrMasterSyncItemStatus;
|
|
errorCode: string | null;
|
|
errorMessage: string | null;
|
|
retryCount: number;
|
|
fieldChanges: Record<string, unknown> | null;
|
|
sourceSummary: Record<string, unknown> | null;
|
|
createdAt: string | null;
|
|
updatedAt: string | null;
|
|
};
|
|
|
|
export type WecomHrMasterSyncRun = {
|
|
id: string;
|
|
mode: WecomHrMasterSyncMode;
|
|
status: WecomHrMasterSyncRunStatus;
|
|
tokenSource: Record<string, string> | null;
|
|
requestedUserids: string[] | null;
|
|
limit: number | null;
|
|
summary: {
|
|
total?: number;
|
|
created?: number;
|
|
updated?: number;
|
|
noop?: number;
|
|
skipped?: number;
|
|
conflicts?: number;
|
|
failed?: number;
|
|
planned?: number;
|
|
success?: number;
|
|
} | null;
|
|
errorCode: string | null;
|
|
errorMessage: string | null;
|
|
triggeredBy: string | null;
|
|
startedAt: string | null;
|
|
finishedAt: string | null;
|
|
createdAt: string | null;
|
|
updatedAt: string | null;
|
|
itemCount?: number;
|
|
items?: WecomHrMasterSyncItem[];
|
|
};
|
|
|
|
export type EmployeeDepartmentSummary = {
|
|
id: string;
|
|
name: string;
|
|
};
|
|
|
|
export type EmployeeSummary = {
|
|
id: string;
|
|
employeeNo: string;
|
|
name: string;
|
|
phone: string;
|
|
email: string;
|
|
status: EmployeeStatus;
|
|
departmentId: string;
|
|
department: EmployeeDepartmentSummary | null;
|
|
directManagerId: string | null;
|
|
directManager: { id: string; employeeNo: string; name: string } | null;
|
|
title: string;
|
|
employmentStatus: EmployeeEmploymentStatus | null;
|
|
hireDate: string | null;
|
|
avatarUrl: string | null;
|
|
roleCodes: string[];
|
|
createdAt: string | null;
|
|
updatedAt: string | null;
|
|
wecomDirectory?: WecomDirectoryState;
|
|
};
|
|
|
|
export type EmployeeListResponse = {
|
|
page: number;
|
|
pageSize: number;
|
|
total: number;
|
|
items: EmployeeSummary[];
|
|
};
|
|
|
|
export type EmployeeLifecycleEvent = {
|
|
id: string;
|
|
employeeId: string;
|
|
eventType: "onboard" | "regularize" | "transfer" | "offboard";
|
|
effectiveDate: string | null;
|
|
payloadJson: Record<string, unknown> | null;
|
|
createdAt: string | null;
|
|
createdBy: string | null;
|
|
};
|
|
|
|
export type EmployeeChecklistTask = {
|
|
id: string;
|
|
employeeId: string;
|
|
scene: "onboarding" | "offboarding" | "transfer";
|
|
taskType:
|
|
| "account_setup"
|
|
| "asset_issue"
|
|
| "policy_ack"
|
|
| "asset_return"
|
|
| "access_revoke"
|
|
| "expense_clearance"
|
|
| "handover_note";
|
|
title: string;
|
|
status: "pending" | "completed" | "skipped";
|
|
dueDate: string | null;
|
|
completedAt: string | null;
|
|
completedBy: string | null;
|
|
payloadJson: Record<string, unknown> | null;
|
|
createdAt: string | null;
|
|
};
|
|
|
|
export type EmployeeOrganizationNode = {
|
|
id: string;
|
|
employeeNo: string;
|
|
name: string;
|
|
title: string;
|
|
status: EmployeeStatus;
|
|
avatarUrl: string | null;
|
|
department: EmployeeDepartmentSummary | null;
|
|
};
|
|
|
|
export type EmployeeContract = {
|
|
id: string;
|
|
employeeId: string;
|
|
contractNo: string;
|
|
contractType: EmployeeContractType;
|
|
startDate: string | null;
|
|
endDate: string | null;
|
|
terminatedDate: string | null;
|
|
attachmentPath: string | null;
|
|
attachmentUrl: string | null;
|
|
status: EmployeeContractStatus;
|
|
createdAt: string | null;
|
|
createdBy: string | null;
|
|
updatedAt: string | null;
|
|
updatedBy: string | null;
|
|
};
|
|
|
|
export type EmployeeTraining = {
|
|
id: string;
|
|
employeeId: string;
|
|
name: string;
|
|
trainingType: EmployeeTrainingType;
|
|
startDate: string | null;
|
|
endDate: string | null;
|
|
status: EmployeeTrainingStatus;
|
|
notes: string | null;
|
|
createdAt: string | null;
|
|
createdBy: string | null;
|
|
updatedAt: string | null;
|
|
updatedBy: string | null;
|
|
};
|
|
|
|
export type EmployeeCertificate = {
|
|
id: string;
|
|
employeeId: string;
|
|
name: string;
|
|
issuer: string;
|
|
obtainedDate: string | null;
|
|
expiryDate: string | null;
|
|
certificateNo: string | null;
|
|
attachmentPath: string | null;
|
|
status: EmployeeCertificateStatus;
|
|
createdAt: string | null;
|
|
createdBy: string | null;
|
|
updatedAt: string | null;
|
|
updatedBy: string | null;
|
|
};
|
|
|
|
export type OrganizationTreeNode = {
|
|
id: string;
|
|
employeeNo: string;
|
|
name: string;
|
|
title: string;
|
|
status: EmployeeStatus;
|
|
avatarUrl: string | null;
|
|
department: EmployeeDepartmentSummary | null;
|
|
externalManager: {
|
|
id: string;
|
|
employeeNo: string;
|
|
name: string;
|
|
department: EmployeeDepartmentSummary | null;
|
|
} | null;
|
|
children: OrganizationTreeNode[];
|
|
};
|
|
|
|
export type OrganizationDepartmentSection = {
|
|
department: EmployeeDepartmentSummary | null;
|
|
roots: OrganizationTreeNode[];
|
|
};
|
|
|
|
export type EmployeeProfile = {
|
|
employee: {
|
|
id: string;
|
|
employeeNo: string;
|
|
name: string;
|
|
phone: string;
|
|
email: string;
|
|
status: EmployeeStatus;
|
|
employmentStatus: EmployeeEmploymentStatus;
|
|
departmentId: string;
|
|
title: string;
|
|
directManagerId: string | null;
|
|
hireDate: string | null;
|
|
probationEndDate: string | null;
|
|
lastWorkingDate: string | null;
|
|
workLocation: string | null;
|
|
emergencyContactName: string | null;
|
|
emergencyContactPhone: string | null;
|
|
notes: string | null;
|
|
avatarUrl: string | null;
|
|
archivedAt: string | null;
|
|
roleCodes: string[];
|
|
department: EmployeeDepartmentSummary | null;
|
|
directManager: { id: string; employeeNo: string; name: string; avatarUrl: string | null } | null;
|
|
wecomDirectory?: WecomDirectoryState;
|
|
};
|
|
lifecycle: {
|
|
events: EmployeeLifecycleEvent[];
|
|
checklistTasks: EmployeeChecklistTask[];
|
|
blockers: {
|
|
openAssetCount: number;
|
|
pendingWorkflowTaskCount: number;
|
|
canCompleteOffboarding: boolean;
|
|
};
|
|
};
|
|
assignedAssets: Array<{
|
|
id: string;
|
|
assetNo: string;
|
|
name: string;
|
|
status: string;
|
|
location: string | null;
|
|
}>;
|
|
organization: {
|
|
reportingChain: EmployeeOrganizationNode[];
|
|
directReports: EmployeeOrganizationNode[];
|
|
};
|
|
};
|
|
|
|
export type FetchEmployeesParams = {
|
|
page: number;
|
|
pageSize: number;
|
|
status?: EmployeeStatus;
|
|
departmentId?: string;
|
|
q?: string;
|
|
title?: string;
|
|
managerId?: string;
|
|
hireDateFrom?: string;
|
|
hireDateTo?: string;
|
|
employmentStatus?: EmployeeEmploymentStatus;
|
|
};
|
|
|
|
export type BatchOperationResult = {
|
|
summary: {
|
|
total: number;
|
|
updated: number;
|
|
};
|
|
employeeIds: string[];
|
|
};
|
|
|
|
export type EmployeeStatsResponse = {
|
|
asOfDate: string;
|
|
employmentStatusSummary: {
|
|
total: number;
|
|
items: Array<{
|
|
status: EmployeeEmploymentStatus;
|
|
count: number;
|
|
}>;
|
|
};
|
|
departmentHeadcount: Array<{
|
|
departmentId: string;
|
|
departmentName: string;
|
|
count: number;
|
|
}>;
|
|
recentMovements: {
|
|
dateFrom: string;
|
|
dateTo: string;
|
|
hires: number;
|
|
departures: number;
|
|
};
|
|
expiringContracts: {
|
|
dateFrom: string;
|
|
dateTo: string;
|
|
count: number;
|
|
};
|
|
certificateSummary: {
|
|
dateFrom: string;
|
|
dateTo: string;
|
|
validHolderCount: number;
|
|
expiringSoonCount: number;
|
|
};
|
|
salarySummary: {
|
|
currentMonth: {
|
|
month: string;
|
|
totalNetAmount: number;
|
|
averageNetAmount: number;
|
|
issuedCount: number;
|
|
} | null;
|
|
previousMonth: {
|
|
month: string;
|
|
totalNetAmount: number;
|
|
averageNetAmount: number;
|
|
issuedCount: number;
|
|
} | null;
|
|
} | null;
|
|
performanceSummary: {
|
|
cycle: {
|
|
id: string;
|
|
name: string;
|
|
cycleType: "monthly" | "quarterly" | "semi_annual" | "annual";
|
|
status: "draft" | "active" | "completed";
|
|
startDate: string | null;
|
|
endDate: string | null;
|
|
} | null;
|
|
averageScore: number | null;
|
|
reviewedCount: number;
|
|
distribution: Array<{
|
|
score: number;
|
|
count: number;
|
|
}>;
|
|
};
|
|
};
|
|
|
|
export type BatchTransferDepartmentPayload = {
|
|
employeeIds: string[];
|
|
departmentId: string;
|
|
};
|
|
|
|
export type BatchToggleUsersPayload = {
|
|
employeeIds: string[];
|
|
};
|
|
|
|
export type BatchSetManagerPayload = {
|
|
employeeIds: string[];
|
|
managerId: string;
|
|
};
|
|
|
|
export async function fetchEmployees(params: FetchEmployeesParams) {
|
|
const search = new URLSearchParams();
|
|
search.set("page", String(params.page));
|
|
search.set("pageSize", String(params.pageSize));
|
|
if (params.status) search.set("status", params.status);
|
|
if (params.departmentId) search.set("departmentId", params.departmentId);
|
|
if (params.q) search.set("q", params.q);
|
|
if (params.title) search.set("title", params.title);
|
|
if (params.managerId) search.set("managerId", params.managerId);
|
|
if (params.hireDateFrom) search.set("hireDateFrom", params.hireDateFrom);
|
|
if (params.hireDateTo) search.set("hireDateTo", params.hireDateTo);
|
|
if (params.employmentStatus) search.set("employmentStatus", params.employmentStatus);
|
|
|
|
return apiRequestData<EmployeeListResponse>(`/api/employees?${search.toString()}`);
|
|
}
|
|
|
|
export async function fetchEmployeeProfile(employeeId: string) {
|
|
return apiRequestData<EmployeeProfile>(`/api/employees/${employeeId}/profile`);
|
|
}
|
|
|
|
export async function uploadEmployeeAvatar(employeeId: string, file: File) {
|
|
const formData = new FormData();
|
|
formData.append("file", file);
|
|
|
|
return apiRequestData<{ employeeId: string; avatarUrl: string | null }>(`/api/employees/${employeeId}/avatar`, {
|
|
method: "PUT",
|
|
body: formData,
|
|
});
|
|
}
|
|
|
|
export async function deleteEmployeeAvatar(employeeId: string) {
|
|
return apiRequestData<{ employeeId: string; avatarUrl: string | null }>(`/api/employees/${employeeId}/avatar`, {
|
|
method: "DELETE",
|
|
});
|
|
}
|
|
|
|
export async function patchEmployeeProfile(
|
|
employeeId: string,
|
|
payload: Partial<{
|
|
departmentId: string;
|
|
directManagerId: string | null;
|
|
title: string;
|
|
hireDate: string | null;
|
|
probationEndDate: string | null;
|
|
lastWorkingDate: string | null;
|
|
workLocation: string | null;
|
|
emergencyContactName: string | null;
|
|
emergencyContactPhone: string | null;
|
|
notes: string | null;
|
|
}>,
|
|
) {
|
|
return apiRequestData<EmployeeProfile>(`/api/employees/${employeeId}/profile`, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function startEmployeeOnboarding(
|
|
employeeId: string,
|
|
payload: { effectiveDate?: string; probationEndDate?: string | null; notes?: string | null } = {},
|
|
) {
|
|
return apiRequestData<EmployeeProfile>(`/api/employees/${employeeId}/onboarding/start`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function regularizeEmployee(
|
|
employeeId: string,
|
|
payload: { effectiveDate?: string; notes?: string | null } = {},
|
|
) {
|
|
return apiRequestData<EmployeeProfile>(`/api/employees/${employeeId}/regularize`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function transferEmployee(
|
|
employeeId: string,
|
|
payload: {
|
|
effectiveDate?: string;
|
|
departmentId?: string;
|
|
directManagerId?: string | null;
|
|
title?: string;
|
|
notes?: string | null;
|
|
} = {},
|
|
) {
|
|
return apiRequestData<EmployeeProfile>(`/api/employees/${employeeId}/transfer`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function startEmployeeOffboarding(
|
|
employeeId: string,
|
|
payload: { effectiveDate?: string; lastWorkingDate?: string | null; notes?: string | null } = {},
|
|
) {
|
|
return apiRequestData<EmployeeProfile>(`/api/employees/${employeeId}/offboarding/start`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function fetchEmployeeLifecycle(employeeId: string) {
|
|
return apiRequestData<EmployeeProfile["lifecycle"]>(`/api/employees/${employeeId}/lifecycle`);
|
|
}
|
|
|
|
export async function fetchEmployeeWecomDirectorySync(employeeId: string) {
|
|
return apiRequestData<{
|
|
employeeId: string;
|
|
wecomDirectory: WecomDirectoryState;
|
|
items: WecomDirectorySyncRun[];
|
|
}>(`/api/employees/${employeeId}/wecom-directory-sync`);
|
|
}
|
|
|
|
export async function retryEmployeeWecomDirectorySync(employeeId: string, operation?: WecomDirectorySyncOperation) {
|
|
return apiRequestData<{
|
|
employeeId: string;
|
|
operation: WecomDirectorySyncOperation;
|
|
result: {
|
|
ok: boolean;
|
|
skipped: boolean;
|
|
status: WecomDirectorySyncStatus;
|
|
code: string;
|
|
message: string | null;
|
|
run: WecomDirectorySyncRun | null;
|
|
} | null;
|
|
wecomDirectory: WecomDirectoryState;
|
|
}>(`/api/employees/${employeeId}/wecom-directory-sync/retry`, {
|
|
method: "POST",
|
|
body: JSON.stringify(operation ? { operation } : {}),
|
|
});
|
|
}
|
|
|
|
export async function runWecomHrMasterSync(payload: {
|
|
mode: WecomHrMasterSyncMode;
|
|
userids?: string[];
|
|
limit?: number;
|
|
}) {
|
|
return apiRequestData<WecomHrMasterSyncRun>("/api/employees/wecom-hr-master-sync/runs", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function fetchWecomHrMasterSyncRuns(pageSize = 5) {
|
|
return apiRequestData<{ items: WecomHrMasterSyncRun[] }>(
|
|
`/api/employees/wecom-hr-master-sync/runs?pageSize=${pageSize}`,
|
|
);
|
|
}
|
|
|
|
export async function fetchWecomHrMasterSyncRun(runId: string) {
|
|
return apiRequestData<WecomHrMasterSyncRun>(`/api/employees/wecom-hr-master-sync/runs/${runId}`);
|
|
}
|
|
|
|
export async function fetchEmployeeOrganization() {
|
|
return apiRequestData<{ items: OrganizationDepartmentSection[] }>("/api/employees/organization");
|
|
}
|
|
|
|
export async function fetchEmployeeStats() {
|
|
return apiRequestData<EmployeeStatsResponse>("/api/employees/stats");
|
|
}
|
|
|
|
export async function fetchEmployeeContracts(employeeId: string) {
|
|
return apiRequestData<{ items: EmployeeContract[] }>(`/api/employees/${employeeId}/contracts`);
|
|
}
|
|
|
|
export async function createEmployeeContract(
|
|
employeeId: string,
|
|
payload: {
|
|
contractNo: string;
|
|
contractType: EmployeeContractType;
|
|
startDate: string;
|
|
endDate: string;
|
|
terminatedDate?: string | null;
|
|
attachmentPath?: string | null;
|
|
},
|
|
) {
|
|
return apiRequestData<EmployeeContract>(`/api/employees/${employeeId}/contracts`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function patchEmployeeContract(
|
|
employeeId: string,
|
|
contractId: string,
|
|
payload: Partial<{
|
|
contractNo: string;
|
|
contractType: EmployeeContractType;
|
|
startDate: string;
|
|
endDate: string;
|
|
terminatedDate: string | null;
|
|
attachmentPath: string | null;
|
|
}>,
|
|
) {
|
|
return apiRequestData<EmployeeContract>(`/api/employees/${employeeId}/contracts/${contractId}`, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function uploadEmployeeContractAttachment(employeeId: string, contractId: string, file: File) {
|
|
const formData = new FormData();
|
|
formData.append("file", file);
|
|
|
|
return apiRequestData<EmployeeContract>(`/api/employees/${employeeId}/contracts/${contractId}/attachment`, {
|
|
method: "PUT",
|
|
body: formData,
|
|
});
|
|
}
|
|
|
|
export async function downloadEmployeeContractAttachment(attachmentUrl: string): Promise<ApiBlobResponse> {
|
|
return apiRequestBlob(attachmentUrl);
|
|
}
|
|
|
|
export async function deleteEmployeeContract(employeeId: string, contractId: string) {
|
|
return apiRequestData<{ contractId: string; deleted: boolean }>(`/api/employees/${employeeId}/contracts/${contractId}`, {
|
|
method: "DELETE",
|
|
});
|
|
}
|
|
|
|
export async function fetchEmployeeTrainings(employeeId: string) {
|
|
return apiRequestData<{ items: EmployeeTraining[] }>(`/api/employees/${employeeId}/trainings`);
|
|
}
|
|
|
|
export async function createEmployeeTraining(
|
|
employeeId: string,
|
|
payload: {
|
|
name: string;
|
|
trainingType: EmployeeTrainingType;
|
|
startDate: string;
|
|
endDate?: string | null;
|
|
status: EmployeeTrainingStatus;
|
|
notes?: string | null;
|
|
},
|
|
) {
|
|
return apiRequestData<EmployeeTraining>(`/api/employees/${employeeId}/trainings`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function patchEmployeeTraining(
|
|
employeeId: string,
|
|
trainingId: string,
|
|
payload: Partial<{
|
|
name: string;
|
|
trainingType: EmployeeTrainingType;
|
|
startDate: string;
|
|
endDate: string | null;
|
|
status: EmployeeTrainingStatus;
|
|
notes: string | null;
|
|
}>,
|
|
) {
|
|
return apiRequestData<EmployeeTraining>(`/api/employees/${employeeId}/trainings/${trainingId}`, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function fetchEmployeeCertificates(employeeId: string) {
|
|
return apiRequestData<{ items: EmployeeCertificate[] }>(`/api/employees/${employeeId}/certificates`);
|
|
}
|
|
|
|
export async function createEmployeeCertificate(
|
|
employeeId: string,
|
|
payload: {
|
|
name: string;
|
|
issuer: string;
|
|
obtainedDate: string;
|
|
expiryDate?: string | null;
|
|
certificateNo?: string | null;
|
|
attachmentPath?: string | null;
|
|
},
|
|
) {
|
|
return apiRequestData<EmployeeCertificate>(`/api/employees/${employeeId}/certificates`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function patchEmployeeCertificate(
|
|
employeeId: string,
|
|
certificateId: string,
|
|
payload: Partial<{
|
|
name: string;
|
|
issuer: string;
|
|
obtainedDate: string;
|
|
expiryDate: string | null;
|
|
certificateNo: string | null;
|
|
attachmentPath: string | null;
|
|
}>,
|
|
) {
|
|
return apiRequestData<EmployeeCertificate>(`/api/employees/${employeeId}/certificates/${certificateId}`, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function completeEmployeeChecklistTask(employeeId: string, taskId: string) {
|
|
return apiRequestData<EmployeeProfile["lifecycle"]>(`/api/employees/${employeeId}/checklist-tasks/${taskId}/complete`, {
|
|
method: "POST",
|
|
body: JSON.stringify({}),
|
|
});
|
|
}
|
|
|
|
export async function skipEmployeeChecklistTask(employeeId: string, taskId: string) {
|
|
return apiRequestData<EmployeeProfile["lifecycle"]>(`/api/employees/${employeeId}/checklist-tasks/${taskId}/skip`, {
|
|
method: "POST",
|
|
body: JSON.stringify({}),
|
|
});
|
|
}
|
|
|
|
export async function batchTransferEmployeesDepartment(payload: BatchTransferDepartmentPayload) {
|
|
return apiRequestData<BatchOperationResult>("/api/users/batch/transfer-department", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function batchEnableUsers(payload: BatchToggleUsersPayload) {
|
|
return apiRequestData<BatchOperationResult>("/api/users/batch/enable", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function batchDisableUsers(payload: BatchToggleUsersPayload) {
|
|
return apiRequestData<BatchOperationResult>("/api/users/batch/disable", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function batchSetEmployeesManager(payload: BatchSetManagerPayload) {
|
|
return apiRequestData<BatchOperationResult>("/api/users/batch/set-manager", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|