1619 lines
44 KiB
TypeScript
1619 lines
44 KiB
TypeScript
import type { RequestFn } from "./utils";
|
|
|
|
export type PayrollLineKind =
|
|
| "earning"
|
|
| "adjustment_credit"
|
|
| "adjustment_debit"
|
|
| "deduction"
|
|
| "payment"
|
|
| "scheduled_change";
|
|
|
|
export type PayrollComponentPeriodScope =
|
|
| "current_only"
|
|
| "current_and_future"
|
|
| "all";
|
|
|
|
export type PayrollPeriodSummary = {
|
|
code: string;
|
|
name: string;
|
|
date_from: string;
|
|
date_to: string;
|
|
pay_date: string | null;
|
|
};
|
|
|
|
export type PayrollAcknowledgement = {
|
|
viewed_at: string | null;
|
|
acknowledged_at: string | null;
|
|
disputed_at: string | null;
|
|
};
|
|
|
|
export type PayrollPaymentConfirmation = {
|
|
confirmed_at: string;
|
|
confirmed_by: {
|
|
id: number;
|
|
display_name: string;
|
|
};
|
|
};
|
|
|
|
export type PayrollStatementSummary = {
|
|
public_id: string;
|
|
period: PayrollPeriodSummary;
|
|
revision: number;
|
|
published_at: string;
|
|
currency: string;
|
|
payable: string;
|
|
acknowledgement: PayrollAcknowledgement | null;
|
|
payment_confirmation: PayrollPaymentConfirmation | null;
|
|
can_confirm_payment: boolean;
|
|
};
|
|
|
|
export type PayrollStatementLine = {
|
|
code: string;
|
|
label: string;
|
|
kind: PayrollLineKind;
|
|
amount: string;
|
|
source_period_from: string | null;
|
|
source_period_to: string | null;
|
|
is_retro: boolean;
|
|
calculated: boolean;
|
|
};
|
|
|
|
export type PayrollStatement = PayrollStatementSummary & {
|
|
point_delta: string | null;
|
|
gross_before_adjustments: string;
|
|
adjustment_total: string;
|
|
gross_total: string;
|
|
deduction_total: string;
|
|
net_pay: string;
|
|
payment_total: string;
|
|
lines: PayrollStatementLine[];
|
|
};
|
|
|
|
export type PayrollStatementPage = {
|
|
count: number;
|
|
next: string | null;
|
|
previous: string | null;
|
|
results: PayrollStatementSummary[];
|
|
};
|
|
|
|
export type PayrollOwnWorkRecord = {
|
|
id: number;
|
|
period_id: number;
|
|
target_points: string;
|
|
target_points_overridden: boolean;
|
|
actual_points: string;
|
|
revision: number;
|
|
status: PayrollApprovalStatus;
|
|
status_label: string;
|
|
lock_version: number;
|
|
replaces_id: number | null;
|
|
reason: string;
|
|
source: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
approved_at: string | null;
|
|
};
|
|
|
|
export type PayrollOwnDailyWorkEntry = {
|
|
id: number;
|
|
period_id: number;
|
|
work_date: string;
|
|
target_points: string;
|
|
actual_points: string;
|
|
note: string;
|
|
lock_version: number;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type PayrollOwnWorkPeriod = PayrollPeriodSummary & {
|
|
id: number;
|
|
status: PayrollPeriodStatus;
|
|
status_label: string;
|
|
editable: boolean;
|
|
record: PayrollOwnWorkRecord | null;
|
|
summary: {
|
|
target_points: string;
|
|
actual_points: string;
|
|
target_source:
|
|
| "saved_record"
|
|
| "individual_schedule"
|
|
| "standard_schedule"
|
|
| "default_schedule";
|
|
workdays_count: number;
|
|
};
|
|
};
|
|
|
|
export type PayrollOwnDailyWorkWorkspace = {
|
|
daily_target_points: string;
|
|
selected_period_id: number | null;
|
|
periods: PayrollOwnWorkPeriod[];
|
|
entries: PayrollOwnDailyWorkEntry[];
|
|
};
|
|
|
|
export type PayrollOwnDailyWorkWrite = {
|
|
period_id: number;
|
|
work_date: string;
|
|
actual_points: string;
|
|
note: string;
|
|
expected_lock_version?: number;
|
|
};
|
|
|
|
export type PayrollOwnDailyWorkSaveResult = {
|
|
operation: "created" | "updated" | "unchanged";
|
|
entry: PayrollOwnDailyWorkEntry;
|
|
record: PayrollOwnWorkRecord;
|
|
};
|
|
|
|
export type PayrollApprovalStatus = "draft" | "approved" | "voided";
|
|
export type PayrollPeriodStatus =
|
|
| "open"
|
|
| "calculated"
|
|
| "review"
|
|
| "approved"
|
|
| "published"
|
|
| "closed";
|
|
export type PayrollRunStatus =
|
|
| "calculated"
|
|
| "review"
|
|
| "approved"
|
|
| "published"
|
|
| "returned"
|
|
| "superseded";
|
|
|
|
export type PayrollAdminUserRef = {
|
|
id: number;
|
|
display_name: string;
|
|
};
|
|
|
|
export type PayrollAdminEmployee = PayrollAdminUserRef & {
|
|
position: string | null;
|
|
department?: string | null;
|
|
};
|
|
|
|
export type PayrollInputHistoryKind = "rates" | "work" | "inputs";
|
|
|
|
export type PayrollInputHistoryEvent = {
|
|
id: number;
|
|
record_id: number;
|
|
action: string;
|
|
action_label: string;
|
|
subject: string;
|
|
employee: PayrollAdminEmployee;
|
|
actor: PayrollAdminUserRef | null;
|
|
created_at: string;
|
|
};
|
|
|
|
export type PayrollManagementAccessCandidate = {
|
|
id: number;
|
|
first_name: string;
|
|
last_name: string;
|
|
patronymic: string;
|
|
email: string;
|
|
display_name: string;
|
|
avatar: string | null;
|
|
};
|
|
|
|
export type PayrollManagementAccessSettings = {
|
|
restricted: boolean;
|
|
management_user_ids: number[];
|
|
management_user_count: number;
|
|
candidates: PayrollManagementAccessCandidate[];
|
|
};
|
|
|
|
export type PayrollAdminPeriod = PayrollPeriodSummary & {
|
|
id: number;
|
|
currency: string;
|
|
status: PayrollPeriodStatus;
|
|
lock_version: number;
|
|
current_run_id: number | null;
|
|
automatic_input_copy?: PayrollInputCopyResult | null;
|
|
};
|
|
|
|
export type PayrollAdminRun = {
|
|
id: number;
|
|
period_id: number;
|
|
revision: number;
|
|
status: PayrollRunStatus;
|
|
employee_count: number;
|
|
gross_total?: string | null;
|
|
deduction_total?: string | null;
|
|
payable_total?: string | null;
|
|
requested_by: PayrollAdminUserRef;
|
|
requested_at: string;
|
|
approved_by: PayrollAdminUserRef | null;
|
|
approved_at: string | null;
|
|
published_by: PayrollAdminUserRef | null;
|
|
published_at: string | null;
|
|
recalculation_reason: string;
|
|
};
|
|
|
|
export type PayrollAdminPermissions = {
|
|
full_access: boolean;
|
|
manage_inputs: boolean;
|
|
approve_inputs: boolean;
|
|
override_approval: boolean;
|
|
calculate: boolean;
|
|
approve_run: boolean;
|
|
publish: boolean;
|
|
view_all: boolean;
|
|
audit: boolean;
|
|
};
|
|
|
|
export type PayrollReadinessGroup = {
|
|
ready: boolean;
|
|
total: number;
|
|
approved: number;
|
|
draft: number;
|
|
missing_employee_ids?: number[];
|
|
};
|
|
|
|
export type PayrollCalculationBlocker = {
|
|
code: string;
|
|
message: string;
|
|
employee_id?: number;
|
|
employee_ids?: number[];
|
|
employee_count?: number;
|
|
count?: number;
|
|
details?: Record<string, unknown>;
|
|
};
|
|
|
|
export type PayrollAdminWorkspace = {
|
|
permissions: PayrollAdminPermissions;
|
|
access_settings: {
|
|
restricted: boolean;
|
|
management_user_count: number;
|
|
can_configure: boolean;
|
|
};
|
|
employees: PayrollAdminEmployee[];
|
|
rate_employees: PayrollAdminEmployee[];
|
|
components: PayrollComponent[];
|
|
periods: PayrollAdminPeriod[];
|
|
selected_period: PayrollAdminPeriod | null;
|
|
readiness: {
|
|
rates: PayrollReadinessGroup;
|
|
work_records: PayrollReadinessGroup;
|
|
input_lines: Pick<PayrollReadinessGroup, "approved" | "draft">;
|
|
calculation: {
|
|
ready: boolean;
|
|
blockers: PayrollCalculationBlocker[];
|
|
};
|
|
};
|
|
current_run: PayrollAdminRun | null;
|
|
runs: PayrollAdminRun[];
|
|
summary: {
|
|
employee_count: number;
|
|
gross_total: string | null;
|
|
deduction_total: string | null;
|
|
payable_total: string | null;
|
|
} | null;
|
|
pending_approvals: {
|
|
rates: number;
|
|
work_records: number;
|
|
input_lines: number;
|
|
};
|
|
carryovers: PayrollCarryoverSummary;
|
|
};
|
|
|
|
export type PayrollCarryoverDirection = "company_owes" | "employee_owes";
|
|
export type PayrollCarryoverStatus = "pending" | "transferred" | "cancelled";
|
|
|
|
export type PayrollCarryoverPeriod = {
|
|
id: number;
|
|
code: string;
|
|
name: string;
|
|
date_from: string;
|
|
date_to: string;
|
|
currency: string;
|
|
};
|
|
|
|
export type PayrollCarryoverSummary = {
|
|
outgoing: number;
|
|
incoming: number;
|
|
pending: number;
|
|
};
|
|
|
|
export type PayrollCarryover = {
|
|
id: number;
|
|
source_period: PayrollCarryoverPeriod;
|
|
target_period: PayrollCarryoverPeriod | null;
|
|
employee: PayrollAdminEmployee;
|
|
direction: PayrollCarryoverDirection;
|
|
direction_label: string;
|
|
amount: string;
|
|
reason: string;
|
|
status: PayrollCarryoverStatus;
|
|
status_label: string;
|
|
generated_input_line_id: number | null;
|
|
created_by: PayrollAdminUserRef;
|
|
created_at: string;
|
|
transferred_at: string | null;
|
|
cancelled_at: string | null;
|
|
can_cancel: boolean;
|
|
};
|
|
|
|
export type PayrollCarryoverWorkspace = {
|
|
period_id: number;
|
|
summary: PayrollCarryoverSummary;
|
|
outgoing: PayrollCarryover[];
|
|
incoming: PayrollCarryover[];
|
|
};
|
|
|
|
export type PayrollCarryoverLedgerEntry = {
|
|
id: number;
|
|
period: PayrollCarryoverPeriod;
|
|
employee: PayrollAdminEmployee;
|
|
component: PayrollComponent;
|
|
amount: string;
|
|
raw_contribution: string;
|
|
contribution: string;
|
|
reason: string;
|
|
status: PayrollApprovalStatus;
|
|
status_label: string;
|
|
include_in_carryover: boolean;
|
|
counts_in_balance: boolean;
|
|
created_by: PayrollAdminUserRef;
|
|
created_at: string;
|
|
};
|
|
|
|
export type PayrollCarryoverLedger = {
|
|
period_id: number;
|
|
currency: string;
|
|
summary: {
|
|
included_count: number;
|
|
excluded_count: number;
|
|
company_owes: string;
|
|
employee_owes: string;
|
|
balance: string;
|
|
};
|
|
entries: PayrollCarryoverLedgerEntry[];
|
|
};
|
|
|
|
export type PayrollCarryoverWrite = {
|
|
employee_id: number;
|
|
direction: PayrollCarryoverDirection;
|
|
amount: string;
|
|
reason: string;
|
|
};
|
|
|
|
export type PayrollCompleteWorkflowResult = {
|
|
period: PayrollAdminPeriod;
|
|
run: PayrollAdminRun;
|
|
completed_steps: string[];
|
|
};
|
|
|
|
export type PayrollPeriodTableStatus =
|
|
| "calculated"
|
|
| "ready"
|
|
| "draft"
|
|
| "incomplete";
|
|
|
|
export type PayrollPeriodTableComponent = {
|
|
code: string;
|
|
label: string;
|
|
kind: PayrollLineKind;
|
|
display_order: number;
|
|
requires_reason: boolean;
|
|
include_in_point_base: boolean;
|
|
include_in_carryover: boolean;
|
|
visible_to_employee: boolean;
|
|
period_scope: PayrollComponentPeriodScope;
|
|
scope_period_id: number | null;
|
|
is_custom: boolean;
|
|
highlight_color: PayrollColumnHighlightColor;
|
|
scheduled_target_component_code: string;
|
|
};
|
|
|
|
export type PayrollCellCommentAuthor = {
|
|
id: number;
|
|
first_name: string;
|
|
last_name: string;
|
|
patronymic: string;
|
|
email: string;
|
|
phone_number: string;
|
|
display_name: string;
|
|
full_name: string;
|
|
avatar: string | null;
|
|
};
|
|
|
|
export type PayrollCellComment = {
|
|
id: number;
|
|
author: PayrollCellCommentAuthor;
|
|
text: string;
|
|
created_at: string;
|
|
};
|
|
|
|
export type PayrollCellCommentSummary = {
|
|
employee_id: number;
|
|
column_id: string;
|
|
count: number;
|
|
latest_at: string;
|
|
};
|
|
|
|
export type PayrollAttendanceAlert = {
|
|
kind: "compensated_absence" | "unconfirmed_absence";
|
|
severity: "warning" | "danger";
|
|
count: number;
|
|
dates: string[];
|
|
points_in_norm: boolean;
|
|
};
|
|
|
|
export type PayrollPeriodTableRow = {
|
|
off_cycle_settlement?: PayrollOffCycleBalance | null;
|
|
employee: PayrollAdminEmployee & {
|
|
first_name: string;
|
|
last_name: string;
|
|
patronymic: string;
|
|
is_active: boolean;
|
|
};
|
|
status: PayrollPeriodTableStatus;
|
|
rate_status: PayrollApprovalStatus | null;
|
|
work_status: PayrollApprovalStatus | null;
|
|
rate_amount: string | null;
|
|
in_norm_point_rate: string | null;
|
|
point_rate: string | null;
|
|
target_points: string | null;
|
|
target_points_automatic: boolean;
|
|
target_points_source: string;
|
|
attendance_points: string | null;
|
|
attendance_alert: PayrollAttendanceAlert | null;
|
|
personnel_points: string;
|
|
actual_points: string | null;
|
|
point_delta: string | null;
|
|
point_amount: string | null;
|
|
component_amounts: Record<string, string>;
|
|
applied_scheduled_changes: Array<{
|
|
target_component_code: string;
|
|
amount: string;
|
|
source_period_id: number;
|
|
source_period_code: string;
|
|
source_component_code: string;
|
|
source_component_name: string;
|
|
}>;
|
|
totals_preliminary: boolean;
|
|
gross_before_adjustments: string | null;
|
|
adjustment_total: string | null;
|
|
gross_total: string | null;
|
|
deduction_total: string | null;
|
|
net_pay: string | null;
|
|
payment_total: string | null;
|
|
payable: string | null;
|
|
opening_balance: string;
|
|
closing_balance: string;
|
|
calculation_issue: {
|
|
code: string;
|
|
message: string;
|
|
point_base: string;
|
|
} | null;
|
|
payment_confirmation: {
|
|
confirmed_at: string;
|
|
confirmed_by: PayrollAdminUserRef;
|
|
} | null;
|
|
};
|
|
|
|
export type PayrollPeriodTableCarryoverSummary = {
|
|
employee_id: number;
|
|
count: number;
|
|
company_owes: string;
|
|
employee_owes: string;
|
|
pending: number;
|
|
};
|
|
|
|
export type PayrollPeriodTable = {
|
|
recorded_payments?: {
|
|
payroll_recorded: string;
|
|
outside_period: string;
|
|
total_recorded: string;
|
|
};
|
|
period_id: number;
|
|
period_status: PayrollPeriodStatus;
|
|
currency: string;
|
|
calculation_rules: {
|
|
ruleset_id: string;
|
|
version: string;
|
|
effective_from: string;
|
|
effective_to: string | null;
|
|
point_policy: "disabled" | "excess_only" | "proportional_with_excess";
|
|
money_quantum: string;
|
|
rounding: "ROUND_HALF_UP" | "ROUND_HALF_EVEN" | "ROUND_DOWN";
|
|
allow_negative_payable: boolean;
|
|
};
|
|
run: Pick<PayrollAdminRun, "id" | "revision" | "status"> | null;
|
|
component_columns: PayrollPeriodTableComponent[];
|
|
cell_comments: PayrollCellCommentSummary[];
|
|
carryovers: PayrollPeriodTableCarryoverSummary[];
|
|
review_mark_employee_ids: number[];
|
|
rows: PayrollPeriodTableRow[];
|
|
summary: {
|
|
employee_count: number;
|
|
calculated_count: number;
|
|
ready_count: number;
|
|
draft_count: number;
|
|
incomplete_count: number;
|
|
preliminary_count: number;
|
|
attendance_alert_employee_count: number;
|
|
attendance_alert_day_count: number;
|
|
calculation_issue_count: number;
|
|
gross_total: string | null;
|
|
deduction_total: string | null;
|
|
payable_total: string | null;
|
|
};
|
|
};
|
|
|
|
export type PayrollPaymentConfirmationResult = {
|
|
statement_id: number;
|
|
employee_id: number;
|
|
confirmed: boolean;
|
|
confirmed_at: string | null;
|
|
confirmed_by: PayrollAdminUserRef | null;
|
|
};
|
|
|
|
export type PayrollPointBreakdownDay = {
|
|
date: string;
|
|
is_workday: boolean;
|
|
attendance_points: string | null;
|
|
attendance_alert: "unconfirmed_absence" | null;
|
|
personnel_points: string | null;
|
|
work_points: string | null;
|
|
attendance_record: {
|
|
id: number;
|
|
arrival_time: string | null;
|
|
departure_time: string | null;
|
|
work_hours: number | null;
|
|
expected_hours: number | null;
|
|
status_label: string;
|
|
issues: string[];
|
|
is_manually_edited: boolean;
|
|
} | null;
|
|
personnel_detail: {
|
|
state: {
|
|
status: string;
|
|
label: string;
|
|
expects_attendance: boolean;
|
|
};
|
|
actions: Array<{
|
|
id: number;
|
|
action: string;
|
|
label: string;
|
|
date: string;
|
|
date_to: string | null;
|
|
comment: string;
|
|
source_request_id: number | null;
|
|
}>;
|
|
requests: Array<{
|
|
id: number;
|
|
type: string;
|
|
type_label: string;
|
|
title: string;
|
|
status: string;
|
|
status_label: string;
|
|
date_from: string | null;
|
|
date_to: string | null;
|
|
comment: string;
|
|
}>;
|
|
};
|
|
work_entry: {
|
|
id: number;
|
|
target_points: string | null;
|
|
actual_points: string | null;
|
|
note: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
} | null;
|
|
};
|
|
|
|
export type PayrollPointBreakdown = {
|
|
period: {
|
|
id: number;
|
|
name: string;
|
|
date_from: string;
|
|
date_to: string;
|
|
};
|
|
employee: PayrollAdminEmployee & { is_active: boolean };
|
|
target_points: string | null;
|
|
actual_points: string | null;
|
|
attendance_alert: PayrollAttendanceAlert | null;
|
|
undated_work_points: string | null;
|
|
undated_work_record: {
|
|
id: number;
|
|
actual_points: string | null;
|
|
note: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
} | null;
|
|
work_points_mode: "daily_entries" | "unavailable";
|
|
dates: PayrollPointBreakdownDay[];
|
|
};
|
|
|
|
export type PayrollComponent = {
|
|
id: string;
|
|
code: string;
|
|
name: string;
|
|
kind: PayrollLineKind;
|
|
kind_label: string;
|
|
requires_reason: boolean;
|
|
is_active: boolean;
|
|
display_order: number;
|
|
period_scope: PayrollComponentPeriodScope;
|
|
scope_period_id: number | null;
|
|
include_in_point_base: boolean;
|
|
include_in_carryover: boolean;
|
|
visible_to_employee: boolean;
|
|
is_custom: boolean;
|
|
highlight_color: PayrollColumnHighlightColor;
|
|
scheduled_target_component_code: string;
|
|
};
|
|
|
|
export type PayrollColumnHighlightColor =
|
|
| ""
|
|
| "green"
|
|
| "red"
|
|
| "amber"
|
|
| "blue"
|
|
| "violet";
|
|
|
|
export type PayrollCustomComponentWrite = {
|
|
name: string;
|
|
kind: PayrollLineKind;
|
|
requires_reason: boolean;
|
|
include_in_point_base: boolean;
|
|
include_in_carryover: boolean;
|
|
visible_to_employee: boolean;
|
|
highlight_color: PayrollColumnHighlightColor;
|
|
period_scope: PayrollComponentPeriodScope;
|
|
scheduled_target_component_code: string;
|
|
};
|
|
|
|
export type PayrollAdminPayRate = {
|
|
id: number;
|
|
employee_id?: number;
|
|
employee: PayrollAdminEmployee;
|
|
rate_code: string;
|
|
amount: string;
|
|
point_rate: string | null;
|
|
currency: string;
|
|
effective_from: string;
|
|
revision: number;
|
|
status: PayrollApprovalStatus;
|
|
reason: string;
|
|
lock_version: number;
|
|
created_by: PayrollAdminUserRef;
|
|
created_at: string;
|
|
approved_by: PayrollAdminUserRef | null;
|
|
approved_at: string | null;
|
|
};
|
|
|
|
export type PayrollAdminWorkRecord = {
|
|
id: number;
|
|
period_id: number;
|
|
employee_id?: number;
|
|
employee: PayrollAdminEmployee;
|
|
target_points: string;
|
|
target_points_overridden: boolean;
|
|
actual_points: string;
|
|
expected_point_amount: string | null;
|
|
expected_gross: string | null;
|
|
expected_recalculated_gross: string | null;
|
|
expected_payable: string | null;
|
|
revision: number;
|
|
status: PayrollApprovalStatus;
|
|
source?: string;
|
|
replaces_id?: number | null;
|
|
reason: string;
|
|
lock_version: number;
|
|
created_by: PayrollAdminUserRef;
|
|
created_at: string;
|
|
approved_by: PayrollAdminUserRef | null;
|
|
approved_at: string | null;
|
|
};
|
|
|
|
export type PayrollAttendanceWorkMode = "missing_only" | "replace_existing";
|
|
|
|
export type PayrollAttendanceWorkAction =
|
|
| "create"
|
|
| "update"
|
|
| "revise"
|
|
| "unchanged"
|
|
| "skip"
|
|
| "blocked";
|
|
|
|
export type PayrollAttendanceWorkIssue = {
|
|
code: string;
|
|
message: string;
|
|
};
|
|
|
|
export type PayrollAttendanceWorkModeSummary = {
|
|
create: number;
|
|
update: number;
|
|
revise: number;
|
|
unchanged: number;
|
|
skip: number;
|
|
blocked: number;
|
|
changes: number;
|
|
};
|
|
|
|
export type PayrollAttendanceExistingWorkRecord = {
|
|
id: number;
|
|
revision: number;
|
|
status: PayrollApprovalStatus;
|
|
source?: string;
|
|
target_points: string;
|
|
actual_points: string;
|
|
created_by?: PayrollAdminUserRef;
|
|
};
|
|
|
|
export type PayrollAttendanceWorkPreviewItem = {
|
|
employee: PayrollAdminEmployee;
|
|
target_points: string;
|
|
actual_points: string;
|
|
daily_target_points: string;
|
|
expected_hours: string;
|
|
worked_hours: string;
|
|
attendance_days: number;
|
|
effective_workdays: number;
|
|
technical_issue_days: number;
|
|
warnings: PayrollAttendanceWorkIssue[];
|
|
blockers: PayrollAttendanceWorkIssue[];
|
|
existing_record: PayrollAttendanceExistingWorkRecord | null;
|
|
actions: Record<PayrollAttendanceWorkMode, PayrollAttendanceWorkAction>;
|
|
};
|
|
|
|
export type PayrollAttendanceWorkPreview = {
|
|
period_id: number;
|
|
generated_at: string;
|
|
preview_token: string;
|
|
policy: {
|
|
code: string;
|
|
label: string;
|
|
description: string;
|
|
formula: string;
|
|
daily_target_points: string;
|
|
};
|
|
summary: {
|
|
attendance_employees: number;
|
|
existing: number;
|
|
blocked: number;
|
|
modes: Record<PayrollAttendanceWorkMode, PayrollAttendanceWorkModeSummary>;
|
|
};
|
|
items: PayrollAttendanceWorkPreviewItem[];
|
|
};
|
|
|
|
export type PayrollAttendanceWorkApplyPayload = {
|
|
mode: PayrollAttendanceWorkMode;
|
|
preview_token: string;
|
|
expected_period_lock_version: number;
|
|
reason: string;
|
|
};
|
|
|
|
export type PayrollAttendanceWorkApplyResult = {
|
|
mode: PayrollAttendanceWorkMode;
|
|
summary: {
|
|
created: number;
|
|
updated: number;
|
|
revised: number;
|
|
unchanged: number;
|
|
skipped: number;
|
|
blocked: number;
|
|
};
|
|
records: PayrollAdminWorkRecord[];
|
|
};
|
|
|
|
export type PayrollWorkbookImportMode = "skip_existing" | "replace_existing";
|
|
|
|
export type PayrollWorkbookImportEmployee = PayrollAdminEmployee & {
|
|
is_active: boolean;
|
|
};
|
|
|
|
export type PayrollWorkbookImportRow = {
|
|
row_key: string;
|
|
sheet_name: string;
|
|
row_number: number;
|
|
source_name: string;
|
|
match_status: "matched" | "ambiguous" | "unmatched";
|
|
matched_employee_id: number | null;
|
|
candidate_employee_ids: number[];
|
|
entry_count: number;
|
|
points_total: string;
|
|
existing_count: number;
|
|
existing_period_record: boolean;
|
|
invalid_cells: Array<{ date: string; message: string }>;
|
|
entries: Array<{ date: string; points: string }>;
|
|
};
|
|
|
|
export type PayrollWorkbookImportPreview = {
|
|
file_name: string;
|
|
file_hash: string;
|
|
period_id: number;
|
|
period_lock_version: number;
|
|
blocks: Array<{ sheet_name: string; year: number; month: number }>;
|
|
employees: PayrollWorkbookImportEmployee[];
|
|
rows: PayrollWorkbookImportRow[];
|
|
summary: {
|
|
rows: number;
|
|
matched: number;
|
|
needs_mapping: number;
|
|
entries: number;
|
|
existing: number;
|
|
invalid: number;
|
|
};
|
|
};
|
|
|
|
export type PayrollWorkbookImportResult = {
|
|
mode: PayrollWorkbookImportMode;
|
|
summary: {
|
|
created: number;
|
|
replaced: number;
|
|
unchanged: number;
|
|
skipped: number;
|
|
};
|
|
record_ids: number[];
|
|
};
|
|
|
|
export type PayrollInputCopyEmployeeScope = "all" | "active" | "selected";
|
|
export type PayrollInputCopyExistingMode = "skip" | "replace";
|
|
|
|
export type PayrollInputCopyPreview = {
|
|
source_period: PayrollAdminPeriod;
|
|
target_period: PayrollAdminPeriod;
|
|
summary: {
|
|
eligible_lines: number;
|
|
employees: number;
|
|
active_employees: number;
|
|
};
|
|
components: Array<
|
|
PayrollComponent & {
|
|
line_count: number;
|
|
employee_count: number;
|
|
amount_total: string;
|
|
}
|
|
>;
|
|
employees: Array<
|
|
PayrollAdminEmployee & {
|
|
is_active: boolean;
|
|
line_count: number;
|
|
component_counts: Record<string, number>;
|
|
existing_component_counts: Record<string, number>;
|
|
}
|
|
>;
|
|
configuration: {
|
|
saved: boolean;
|
|
component_codes: string[];
|
|
employee_scope: PayrollInputCopyEmployeeScope;
|
|
employee_ids: number[];
|
|
existing_mode: PayrollInputCopyExistingMode;
|
|
auto_apply_on_period_creation: boolean;
|
|
};
|
|
};
|
|
|
|
export type PayrollInputCopyWrite = {
|
|
source_period_id: number;
|
|
component_codes: string[];
|
|
employee_scope: PayrollInputCopyEmployeeScope;
|
|
employee_ids: number[];
|
|
existing_mode: PayrollInputCopyExistingMode;
|
|
expected_period_lock_version: number;
|
|
idempotency_key: string;
|
|
remember_configuration: boolean;
|
|
auto_apply_on_period_creation: boolean;
|
|
};
|
|
|
|
export type PayrollInputCopyResult = {
|
|
source_period_id: number;
|
|
target_period_id: number;
|
|
summary: {
|
|
created: number;
|
|
employees: number;
|
|
skipped: number;
|
|
replaced_cells: number;
|
|
voided: number;
|
|
};
|
|
record_ids: number[];
|
|
idempotent_replay: boolean;
|
|
};
|
|
|
|
export type PayrollAdminInputLine = {
|
|
id: number;
|
|
period_id: number;
|
|
employee: PayrollAdminEmployee;
|
|
employee_id?: number;
|
|
component: PayrollComponent;
|
|
component_code: string;
|
|
amount: string;
|
|
relates_to_period_id: number | null;
|
|
relates_to_period: PayrollCarryoverPeriod | null;
|
|
is_automatic_carryover: boolean;
|
|
include_in_carryover: boolean;
|
|
reason: string;
|
|
status: PayrollApprovalStatus;
|
|
lock_version: number;
|
|
created_by: PayrollAdminUserRef;
|
|
created_at: string;
|
|
approved_by: PayrollAdminUserRef | null;
|
|
approved_at: string | null;
|
|
};
|
|
|
|
export type PayrollAdminPage<T> = {
|
|
count: number;
|
|
next: string | null;
|
|
previous: string | null;
|
|
results: T[];
|
|
};
|
|
|
|
export type PayrollAdminListPayload<T> = PayrollAdminPage<T> | T[];
|
|
|
|
export type PayrollPeriodWrite = {
|
|
code: string;
|
|
name: string;
|
|
date_from: string;
|
|
date_to: string;
|
|
pay_date: string | null;
|
|
currency: string;
|
|
};
|
|
|
|
export type PayrollPayRateWrite = {
|
|
employee_id: number;
|
|
rate_code: string;
|
|
amount: string;
|
|
point_rate: string | null;
|
|
currency: string;
|
|
effective_from: string;
|
|
reason: string;
|
|
};
|
|
|
|
export type PayrollBulkPointRateMode = "fixed" | "in_norm";
|
|
|
|
export type PayrollBulkPointRateWrite = {
|
|
employee_ids: number[];
|
|
mode: PayrollBulkPointRateMode;
|
|
point_rate?: string | null;
|
|
reason: string;
|
|
};
|
|
|
|
export type PayrollBulkPointRateResult = {
|
|
mode: PayrollBulkPointRateMode;
|
|
point_rate: string | null;
|
|
summary: {
|
|
selected_employees: number;
|
|
updated_drafts: number;
|
|
created_revisions: number;
|
|
unchanged: number;
|
|
skipped: number;
|
|
};
|
|
};
|
|
|
|
export type PayrollBulkPayRateWrite = {
|
|
employee_ids: number[];
|
|
amount: string;
|
|
effective_from: string;
|
|
reason: string;
|
|
};
|
|
|
|
export type PayrollBulkPayRateResult = {
|
|
amount: string;
|
|
effective_from: string;
|
|
summary: {
|
|
selected_employees: number;
|
|
created_drafts: number;
|
|
updated_drafts: number;
|
|
created_revisions: number;
|
|
unchanged: number;
|
|
skipped: number;
|
|
};
|
|
};
|
|
|
|
export type PayrollBulkTargetPointsMode = "fixed" | "automatic";
|
|
|
|
export type PayrollBulkTargetPointsWrite = {
|
|
employee_ids: number[];
|
|
mode: PayrollBulkTargetPointsMode;
|
|
target_points?: string | null;
|
|
reason: string;
|
|
};
|
|
|
|
export type PayrollBulkTargetPointsResult = {
|
|
mode: PayrollBulkTargetPointsMode;
|
|
target_points: string | null;
|
|
summary: {
|
|
selected_employees: number;
|
|
created_drafts: number;
|
|
updated_drafts: number;
|
|
created_revisions: number;
|
|
unchanged: number;
|
|
skipped: number;
|
|
};
|
|
};
|
|
|
|
export type PayrollApproveDraftsResult = {
|
|
period_id: number;
|
|
summary: {
|
|
rates: number;
|
|
work_records: number;
|
|
input_lines: number;
|
|
total: number;
|
|
};
|
|
};
|
|
|
|
export type PayrollWorkRecordWrite = {
|
|
period_id: number;
|
|
employee_id: number;
|
|
target_points?: string | null;
|
|
actual_points: string;
|
|
expected_point_amount?: string | null;
|
|
expected_gross?: string | null;
|
|
expected_recalculated_gross?: string | null;
|
|
expected_payable?: string | null;
|
|
reason: string;
|
|
};
|
|
|
|
export type PayrollInputLineWrite = {
|
|
period_id: number;
|
|
employee_id: number;
|
|
component_code: string;
|
|
amount: string;
|
|
relates_to_period_id?: number | null;
|
|
reason: string;
|
|
};
|
|
|
|
type PayrollAdminListParams = {
|
|
period_id?: number;
|
|
search?: string;
|
|
status?: PayrollApprovalStatus | "";
|
|
};
|
|
|
|
const adminPrefix = "/api/v1/finance/payroll/admin";
|
|
|
|
function buildQuery(
|
|
params: Record<string, string | number | boolean | undefined | null>,
|
|
): string {
|
|
const search = new URLSearchParams();
|
|
Object.entries(params).forEach(([key, value]) => {
|
|
if (value !== undefined && value !== null && value !== "")
|
|
search.set(key, String(value));
|
|
});
|
|
const query = search.toString();
|
|
return query ? `?${query}` : "";
|
|
}
|
|
|
|
function jsonOptions(
|
|
method: "POST" | "PATCH" | "DELETE",
|
|
payload: object = {},
|
|
): RequestInit {
|
|
return { method, body: JSON.stringify(payload) };
|
|
}
|
|
|
|
export type PayrollOffCyclePayment = {
|
|
settlement: PayrollOffCycleBalance | null;
|
|
id: number;
|
|
employee_id: number | null;
|
|
payee_name: string;
|
|
paid_on: string;
|
|
amount: string;
|
|
currency: string;
|
|
source_period_id: number | null;
|
|
source_period_name: string | null;
|
|
note: string;
|
|
created_at: string;
|
|
created_by: PayrollAdminUserRef;
|
|
voided_at: string | null;
|
|
voided_by: PayrollAdminUserRef | null;
|
|
void_reason: string;
|
|
};
|
|
|
|
export type PayrollOffCyclePaymentWrite = {
|
|
employee_id: number | null;
|
|
payee_name: string;
|
|
paid_on: string;
|
|
amount: string;
|
|
currency: string;
|
|
source_period_id: number | null;
|
|
note: string;
|
|
request_id: string;
|
|
};
|
|
|
|
export type PayrollOffCyclePaymentQuery = {
|
|
date_from?: string;
|
|
date_to?: string;
|
|
employee_id?: number;
|
|
source_period_id?: number;
|
|
search?: string;
|
|
currency?: string;
|
|
include_voided?: boolean;
|
|
page?: number;
|
|
};
|
|
|
|
export type PayrollOffCyclePaymentPage = {
|
|
results: PayrollOffCyclePayment[];
|
|
count: number;
|
|
page: number;
|
|
page_size: number;
|
|
total_paid: string;
|
|
currency: string;
|
|
};
|
|
|
|
export type PayrollOffCycleBalance = {
|
|
original_payable: string;
|
|
paid_outside_period: string;
|
|
remaining: string;
|
|
confirmed: boolean;
|
|
};
|
|
|
|
export type PayrollOffCycleSettlement = PayrollOffCycleBalance & {
|
|
currency: string;
|
|
};
|
|
|
|
export function createFinanceApi(request: RequestFn) {
|
|
return {
|
|
getPayrollOffCyclePayments: (
|
|
params: PayrollOffCyclePaymentQuery,
|
|
): Promise<PayrollOffCyclePaymentPage> =>
|
|
request(`${adminPrefix}/off-cycle-payments/${buildQuery(params)}`),
|
|
recordPayrollOffCyclePayment: (
|
|
payload: PayrollOffCyclePaymentWrite,
|
|
): Promise<PayrollOffCyclePayment> =>
|
|
request(
|
|
`${adminPrefix}/off-cycle-payments/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
voidPayrollOffCyclePayment: (
|
|
id: number,
|
|
reason: string,
|
|
): Promise<PayrollOffCyclePayment> =>
|
|
request(
|
|
`${adminPrefix}/off-cycle-payments/${id}/void/`,
|
|
jsonOptions("POST", { reason }),
|
|
),
|
|
getPayrollOffCycleSettlement: (
|
|
periodId: number,
|
|
employeeId: number,
|
|
): Promise<PayrollOffCycleSettlement> =>
|
|
request(`${adminPrefix}/off-cycle-settlement/${periodId}/${employeeId}/`),
|
|
getMyPayrollStatements: (): Promise<
|
|
PayrollStatementPage | PayrollStatementSummary[]
|
|
> => request("/api/v1/finance/payroll/me/statements/?page_size=100"),
|
|
getMyPayrollStatement: (publicId: string): Promise<PayrollStatement> =>
|
|
request(
|
|
`/api/v1/finance/payroll/me/statements/${encodeURIComponent(publicId)}/`,
|
|
),
|
|
acknowledgeMyPayrollStatement: (
|
|
publicId: string,
|
|
): Promise<PayrollAcknowledgement> =>
|
|
request(
|
|
`/api/v1/finance/payroll/me/statements/${encodeURIComponent(publicId)}/acknowledge/`,
|
|
{ method: "POST" },
|
|
),
|
|
setMyPayrollStatementPaymentConfirmation: (
|
|
publicId: string,
|
|
confirmed: boolean,
|
|
): Promise<{ payment_confirmation: PayrollPaymentConfirmation | null }> =>
|
|
request(
|
|
`/api/v1/finance/payroll/me/statements/${encodeURIComponent(publicId)}/payment-confirmation/`,
|
|
jsonOptions("POST", { confirmed }),
|
|
),
|
|
getMyPayrollDailyWork: (
|
|
periodId?: number,
|
|
): Promise<PayrollOwnDailyWorkWorkspace> =>
|
|
request(
|
|
`/api/v1/finance/payroll/me/work-records/${buildQuery({ period_id: periodId })}`,
|
|
),
|
|
saveMyPayrollDailyWorkEntry: (
|
|
payload: PayrollOwnDailyWorkWrite,
|
|
): Promise<PayrollOwnDailyWorkSaveResult> =>
|
|
request(
|
|
"/api/v1/finance/payroll/me/work-records/",
|
|
jsonOptions("POST", payload),
|
|
),
|
|
getPayrollManagementAccessSettings:
|
|
(): Promise<PayrollManagementAccessSettings> =>
|
|
request("/api/v1/finance/payroll/management-access/"),
|
|
updatePayrollManagementAccessSettings: (
|
|
managementUserIds: number[],
|
|
): Promise<PayrollManagementAccessSettings> =>
|
|
request(
|
|
"/api/v1/finance/payroll/management-access/",
|
|
jsonOptions("PATCH", { management_user_ids: managementUserIds }),
|
|
),
|
|
getPayrollAdminWorkspace: (
|
|
periodId?: number,
|
|
): Promise<PayrollAdminWorkspace> =>
|
|
request(
|
|
`${adminPrefix}/workspace/${buildQuery({ period_id: periodId })}`,
|
|
),
|
|
createPayrollAdminComponent: (
|
|
payload: PayrollCustomComponentWrite & { period_id: number },
|
|
): Promise<PayrollComponent> =>
|
|
request(`${adminPrefix}/components/`, jsonOptions("POST", payload)),
|
|
updatePayrollAdminComponent: (
|
|
code: string,
|
|
payload: PayrollCustomComponentWrite & { period_id: number },
|
|
): Promise<PayrollComponent> =>
|
|
request(
|
|
`${adminPrefix}/components/${encodeURIComponent(code)}/`,
|
|
jsonOptions("PATCH", payload),
|
|
),
|
|
hidePayrollAdminComponent: (
|
|
code: string,
|
|
periodId: number,
|
|
mode: "current" | "current_and_future",
|
|
): Promise<void> =>
|
|
request(`${adminPrefix}/components/${encodeURIComponent(code)}/`, {
|
|
...jsonOptions("DELETE", { period_id: periodId, mode }),
|
|
}),
|
|
getPayrollAdminPeriods: (): Promise<
|
|
PayrollAdminListPayload<PayrollAdminPeriod>
|
|
> => request(`${adminPrefix}/periods/`),
|
|
getPayrollAdminPeriodTable: (
|
|
periodId: number,
|
|
): Promise<PayrollPeriodTable> =>
|
|
request(`${adminPrefix}/periods/${periodId}/table/`),
|
|
setPayrollAdminTableReviewMark: (
|
|
periodId: number,
|
|
employeeId: number,
|
|
checked: boolean,
|
|
): Promise<{ employee_ids: number[] }> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/table-review-marks/`,
|
|
jsonOptions("POST", { employee_id: employeeId, checked }),
|
|
),
|
|
clearPayrollAdminTableReviewMarks: (
|
|
periodId: number,
|
|
): Promise<{ employee_ids: number[] }> =>
|
|
request(`${adminPrefix}/periods/${periodId}/table-review-marks/`, {
|
|
method: "DELETE",
|
|
}),
|
|
setPayrollAdminPaymentConfirmation: (
|
|
periodId: number,
|
|
employeeId: number,
|
|
confirmed: boolean,
|
|
): Promise<PayrollPaymentConfirmationResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/employees/${employeeId}/payment-confirmation/`,
|
|
jsonOptions("POST", { confirmed }),
|
|
),
|
|
getPayrollAdminCarryovers: (
|
|
periodId: number,
|
|
): Promise<PayrollCarryoverLedger> =>
|
|
request(`${adminPrefix}/periods/${periodId}/carryovers/`),
|
|
setPayrollAdminInputLineCarryoverInclusion: (
|
|
lineId: number,
|
|
included: boolean,
|
|
): Promise<{
|
|
id: number;
|
|
include_in_carryover: boolean;
|
|
message: string;
|
|
}> =>
|
|
request(
|
|
`${adminPrefix}/input-lines/${lineId}/carryover-inclusion/`,
|
|
jsonOptions("PATCH", { included }),
|
|
),
|
|
createPayrollAdminCarryover: (
|
|
periodId: number,
|
|
payload: PayrollCarryoverWrite,
|
|
): Promise<PayrollCarryover> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/carryovers/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
cancelPayrollAdminCarryover: (
|
|
carryoverId: number,
|
|
): Promise<PayrollCarryover> =>
|
|
request(`${adminPrefix}/carryovers/${carryoverId}/`, {
|
|
method: "DELETE",
|
|
}),
|
|
getPayrollAdminCellComments: (
|
|
periodId: number,
|
|
employeeId: number,
|
|
columnId: string,
|
|
): Promise<PayrollCellComment[]> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/employees/${employeeId}/cells/${encodeURIComponent(columnId)}/comments/`,
|
|
),
|
|
addPayrollAdminCellComment: (
|
|
periodId: number,
|
|
employeeId: number,
|
|
columnId: string,
|
|
text: string,
|
|
): Promise<PayrollCellComment> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/employees/${employeeId}/cells/${encodeURIComponent(columnId)}/comments/`,
|
|
jsonOptions("POST", { text }),
|
|
),
|
|
deletePayrollAdminCellComment: (
|
|
periodId: number,
|
|
employeeId: number,
|
|
columnId: string,
|
|
commentId: number,
|
|
): Promise<void> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/employees/${employeeId}/cells/${encodeURIComponent(columnId)}/comments/${commentId}/`,
|
|
{ method: "DELETE" },
|
|
),
|
|
getPayrollAdminPointBreakdown: (
|
|
periodId: number,
|
|
employeeId: number,
|
|
): Promise<PayrollPointBreakdown> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/employees/${employeeId}/point-breakdown/`,
|
|
),
|
|
createPayrollAdminPeriod: (
|
|
payload: PayrollPeriodWrite,
|
|
): Promise<PayrollAdminPeriod> =>
|
|
request(`${adminPrefix}/periods/`, jsonOptions("POST", payload)),
|
|
updatePayrollAdminPeriod: (
|
|
periodId: number,
|
|
payload: Partial<PayrollPeriodWrite> & { expected_lock_version: number },
|
|
): Promise<PayrollAdminPeriod> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/`,
|
|
jsonOptions("PATCH", payload),
|
|
),
|
|
getPayrollAdminPayRates: (
|
|
params: PayrollAdminListParams = {},
|
|
): Promise<PayrollAdminListPayload<PayrollAdminPayRate>> =>
|
|
request(
|
|
`${adminPrefix}/pay-rates/${buildQuery({ ...params, page_size: 200 })}`,
|
|
),
|
|
getPayrollAdminInputHistory: (
|
|
periodId: number,
|
|
kind: PayrollInputHistoryKind,
|
|
): Promise<PayrollInputHistoryEvent[]> =>
|
|
request(
|
|
`${adminPrefix}/history/${buildQuery({ period_id: periodId, kind })}`,
|
|
),
|
|
createPayrollAdminPayRate: (
|
|
payload: PayrollPayRateWrite,
|
|
): Promise<PayrollAdminPayRate> =>
|
|
request(`${adminPrefix}/pay-rates/`, jsonOptions("POST", payload)),
|
|
updatePayrollAdminPayRate: (
|
|
rateId: number,
|
|
payload: Partial<
|
|
Omit<PayrollPayRateWrite, "employee_id" | "rate_code" | "currency">
|
|
> & { expected_lock_version: number },
|
|
): Promise<PayrollAdminPayRate> =>
|
|
request(
|
|
`${adminPrefix}/pay-rates/${rateId}/`,
|
|
jsonOptions("PATCH", payload),
|
|
),
|
|
approvePayrollAdminPayRate: (
|
|
rateId: number,
|
|
expectedLockVersion: number,
|
|
): Promise<PayrollAdminPayRate> =>
|
|
request(
|
|
`${adminPrefix}/pay-rates/${rateId}/approve/`,
|
|
jsonOptions("POST", { expected_lock_version: expectedLockVersion }),
|
|
),
|
|
revisePayrollAdminPayRate: (
|
|
rateId: number,
|
|
reason: string,
|
|
): Promise<PayrollAdminPayRate> =>
|
|
request(
|
|
`${adminPrefix}/pay-rates/${rateId}/revise/`,
|
|
jsonOptions("POST", { reason }),
|
|
),
|
|
bulkCreatePayrollAdminPayRates: (
|
|
periodId: number,
|
|
payload: PayrollBulkPayRateWrite,
|
|
): Promise<PayrollBulkPayRateResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/bulk-pay-rate/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
bulkSetPayrollAdminPointRate: (
|
|
periodId: number,
|
|
payload: PayrollBulkPointRateWrite,
|
|
): Promise<PayrollBulkPointRateResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/bulk-point-rate/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
bulkSetPayrollAdminTargetPoints: (
|
|
periodId: number,
|
|
payload: PayrollBulkTargetPointsWrite,
|
|
): Promise<PayrollBulkTargetPointsResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/bulk-target-points/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
getPayrollAdminInputCopyPreview: (
|
|
periodId: number,
|
|
sourcePeriodId: number,
|
|
): Promise<PayrollInputCopyPreview> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/copy-input-lines/${buildQuery({ source_period_id: sourcePeriodId })}`,
|
|
),
|
|
copyPayrollAdminInputLines: (
|
|
periodId: number,
|
|
payload: PayrollInputCopyWrite,
|
|
): Promise<PayrollInputCopyResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/copy-input-lines/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
approveAllPayrollAdminDrafts: (
|
|
periodId: number,
|
|
): Promise<PayrollApproveDraftsResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/approve-drafts/`,
|
|
jsonOptions("POST"),
|
|
),
|
|
getPayrollAdminWorkRecords: (
|
|
params: PayrollAdminListParams = {},
|
|
): Promise<PayrollAdminListPayload<PayrollAdminWorkRecord>> =>
|
|
request(
|
|
`${adminPrefix}/work-records/${buildQuery({ ...params, page_size: 200 })}`,
|
|
),
|
|
createPayrollAdminWorkRecord: (
|
|
payload: PayrollWorkRecordWrite,
|
|
): Promise<PayrollAdminWorkRecord> =>
|
|
request(`${adminPrefix}/work-records/`, jsonOptions("POST", payload)),
|
|
updatePayrollAdminWorkRecord: (
|
|
recordId: number,
|
|
payload: Partial<
|
|
Omit<PayrollWorkRecordWrite, "period_id" | "employee_id">
|
|
> & { expected_lock_version: number },
|
|
): Promise<PayrollAdminWorkRecord> =>
|
|
request(
|
|
`${adminPrefix}/work-records/${recordId}/`,
|
|
jsonOptions("PATCH", payload),
|
|
),
|
|
approvePayrollAdminWorkRecord: (
|
|
recordId: number,
|
|
expectedLockVersion: number,
|
|
): Promise<PayrollAdminWorkRecord> =>
|
|
request(
|
|
`${adminPrefix}/work-records/${recordId}/approve/`,
|
|
jsonOptions("POST", { expected_lock_version: expectedLockVersion }),
|
|
),
|
|
revisePayrollAdminWorkRecord: (
|
|
recordId: number,
|
|
reason: string,
|
|
): Promise<PayrollAdminWorkRecord> =>
|
|
request(
|
|
`${adminPrefix}/work-records/${recordId}/revise/`,
|
|
jsonOptions("POST", { reason }),
|
|
),
|
|
getPayrollAdminAttendanceWorkPreview: (
|
|
periodId: number,
|
|
): Promise<PayrollAttendanceWorkPreview> =>
|
|
request(`${adminPrefix}/periods/${periodId}/attendance-work-records/`),
|
|
applyPayrollAdminAttendanceWork: (
|
|
periodId: number,
|
|
payload: PayrollAttendanceWorkApplyPayload,
|
|
): Promise<PayrollAttendanceWorkApplyResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/attendance-work-records/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
previewPayrollAdminWorkbookImport: (
|
|
periodId: number,
|
|
file: File,
|
|
): Promise<PayrollWorkbookImportPreview> => {
|
|
const body = new FormData();
|
|
body.append("file", file);
|
|
return request(
|
|
`${adminPrefix}/periods/${periodId}/workbook-import/preview/`,
|
|
{
|
|
method: "POST",
|
|
body,
|
|
},
|
|
);
|
|
},
|
|
applyPayrollAdminWorkbookImport: (
|
|
periodId: number,
|
|
payload: {
|
|
file: File;
|
|
mode: PayrollWorkbookImportMode;
|
|
mappings: Record<string, number | null>;
|
|
expected_file_hash: string;
|
|
expected_period_lock_version: number;
|
|
},
|
|
): Promise<PayrollWorkbookImportResult> => {
|
|
const body = new FormData();
|
|
body.append("file", payload.file);
|
|
body.append("mode", payload.mode);
|
|
body.append("mappings", JSON.stringify(payload.mappings));
|
|
body.append("expected_file_hash", payload.expected_file_hash);
|
|
body.append(
|
|
"expected_period_lock_version",
|
|
String(payload.expected_period_lock_version),
|
|
);
|
|
return request(
|
|
`${adminPrefix}/periods/${periodId}/workbook-import/apply/`,
|
|
{
|
|
method: "POST",
|
|
body,
|
|
},
|
|
);
|
|
},
|
|
getPayrollAdminInputLines: (
|
|
params: PayrollAdminListParams = {},
|
|
): Promise<PayrollAdminListPayload<PayrollAdminInputLine>> =>
|
|
request(
|
|
`${adminPrefix}/input-lines/${buildQuery({ ...params, page_size: 200 })}`,
|
|
),
|
|
createPayrollAdminInputLine: (
|
|
payload: PayrollInputLineWrite,
|
|
): Promise<PayrollAdminInputLine> =>
|
|
request(`${adminPrefix}/input-lines/`, jsonOptions("POST", payload)),
|
|
updatePayrollAdminInputLine: (
|
|
lineId: number,
|
|
payload: Partial<
|
|
Omit<
|
|
PayrollInputLineWrite,
|
|
"period_id" | "employee_id" | "component_code"
|
|
>
|
|
> & { expected_lock_version: number },
|
|
): Promise<PayrollAdminInputLine> =>
|
|
request(
|
|
`${adminPrefix}/input-lines/${lineId}/`,
|
|
jsonOptions("PATCH", payload),
|
|
),
|
|
clearPayrollAdminComponentCell: (
|
|
periodId: number,
|
|
payload: { employee_id: number; component_code: string },
|
|
): Promise<{ draft: number; approved: number; total: number }> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/component-cell/clear/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
setPayrollAdminComponentCell: (
|
|
periodId: number,
|
|
payload: { employee_id: number; component_code: string; amount: string },
|
|
): Promise<PayrollAdminInputLine> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/component-cell/set/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
approvePayrollAdminInputLine: (
|
|
lineId: number,
|
|
expectedLockVersion: number,
|
|
): Promise<PayrollAdminInputLine> =>
|
|
request(
|
|
`${adminPrefix}/input-lines/${lineId}/approve/`,
|
|
jsonOptions("POST", { expected_lock_version: expectedLockVersion }),
|
|
),
|
|
calculatePayrollAdminPeriod: (
|
|
periodId: number,
|
|
payload: {
|
|
idempotency_key: string;
|
|
recalculation_reason: string;
|
|
expected_lock_version: number;
|
|
},
|
|
): Promise<PayrollAdminRun> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/calculate/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
completePayrollAdminPeriodWorkflow: (
|
|
periodId: number,
|
|
payload: {
|
|
idempotency_key: string;
|
|
recalculation_reason: string;
|
|
expected_lock_version: number;
|
|
},
|
|
): Promise<PayrollCompleteWorkflowResult> =>
|
|
request(
|
|
`${adminPrefix}/periods/${periodId}/complete-workflow/`,
|
|
jsonOptions("POST", payload),
|
|
),
|
|
submitPayrollAdminRunForReview: (runId: number): Promise<PayrollAdminRun> =>
|
|
request(
|
|
`${adminPrefix}/runs/${runId}/submit-review/`,
|
|
jsonOptions("POST"),
|
|
),
|
|
returnPayrollAdminRun: (
|
|
runId: number,
|
|
reason: string,
|
|
): Promise<PayrollAdminRun> =>
|
|
request(
|
|
`${adminPrefix}/runs/${runId}/return/`,
|
|
jsonOptions("POST", { reason }),
|
|
),
|
|
approvePayrollAdminRun: (runId: number): Promise<PayrollAdminRun> =>
|
|
request(`${adminPrefix}/runs/${runId}/approve/`, jsonOptions("POST")),
|
|
publishPayrollAdminRun: (runId: number): Promise<PayrollAdminRun> =>
|
|
request(`${adminPrefix}/runs/${runId}/publish/`, jsonOptions("POST")),
|
|
closePayrollAdminPeriod: (periodId: number): Promise<PayrollAdminPeriod> =>
|
|
request(`${adminPrefix}/periods/${periodId}/close/`, jsonOptions("POST")),
|
|
};
|
|
}
|