Skip to content

Commit 956b60c

Browse files
authored
feat: Implement Batching for Payroll Updates (#764)
feat: implement batching for payroll updates to support v2025-06-15 API changes - Update PayrollConfiguration and PayrollEditEmployee to use useBatchedMutation - Set batch size to 100 to align with API maximum for employee compensations - Simplify implementation by passing inline async functions to useBatchedMutation - Remove unnecessary useCallback wrappers as useBatchedMutation handles refs internally - Future-proofs components for bulk payroll update operations
1 parent 024f8a8 commit 956b60c

File tree

2 files changed

+38
-24
lines changed

2 files changed

+38
-24
lines changed

src/components/Payroll/PayrollConfiguration/PayrollConfiguration.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { PayrollUpdateEmployeeCompensations } from '@gusto/embedded-api/mod
1212
import { usePreparedPayrollData } from '../usePreparedPayrollData'
1313
import { payrollSubmitHandler, type ApiPayrollBlocker } from '../PayrollBlocker/payrollHelpers'
1414
import { PayrollConfigurationPresentation } from './PayrollConfigurationPresentation'
15+
import { useBatchedMutation } from '@/hooks/useBatchedMutation'
1516
import type { BaseComponentInterface } from '@/components/Base/Base'
1617
import { BaseComponent } from '@/components/Base/Base'
1718
import { componentEvents } from '@/shared/constants'
@@ -112,7 +113,21 @@ export const Root = ({
112113

113114
const { mutateAsync: calculatePayroll } = usePayrollsCalculateMutation()
114115

115-
const { mutateAsync: updatePayroll, isPending: isUpdatingPayroll } = usePayrollsUpdateMutation()
116+
const { mutateAsync: baseUpdatePayroll } = usePayrollsUpdateMutation()
117+
118+
const { mutateAsync: updatePayroll, isPending: isUpdatingPayroll } = useBatchedMutation(
119+
async (batch: PayrollUpdateEmployeeCompensations[]) => {
120+
const result = await baseUpdatePayroll({
121+
request: {
122+
companyId,
123+
payrollId,
124+
payrollUpdate: { employeeCompensations: batch },
125+
},
126+
})
127+
return result.payrollPrepared!
128+
},
129+
{ batchSize: 100 },
130+
)
116131

117132
const {
118133
preparedPayroll,
@@ -170,19 +185,11 @@ export const Root = ({
170185
})
171186
await baseSubmitHandler({}, async () => {
172187
const transformedCompensation = transformEmployeeCompensation(employeeCompensation)
173-
const result = await updatePayroll({
174-
request: {
175-
companyId,
176-
payrollId,
177-
payrollUpdate: {
178-
employeeCompensations: [
179-
{ ...transformedCompensation, excluded: !transformedCompensation.excluded },
180-
],
181-
},
182-
},
183-
})
188+
const [result] = await updatePayroll([
189+
{ ...transformedCompensation, excluded: !transformedCompensation.excluded },
190+
])
184191
onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SAVED, {
185-
payrollPrepared: result.payrollPrepared,
192+
payrollPrepared: result,
186193
})
187194
// Refresh preparedPayroll to get updated data
188195
await handlePreparePayroll()

src/components/Payroll/PayrollEditEmployee/PayrollEditEmployee.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { PayrollUpdateEmployeeCompensations } from '@gusto/embedded-api/mod
55
import { useMemo } from 'react'
66
import { usePreparedPayrollData } from '../usePreparedPayrollData'
77
import { PayrollEditEmployeePresentation } from './PayrollEditEmployeePresentation'
8+
import { useBatchedMutation } from '@/hooks/useBatchedMutation'
89
import { componentEvents } from '@/shared/constants'
910
import type { BaseComponentInterface } from '@/components/Base/Base'
1011
import { BaseComponent } from '@/components/Base/Base'
@@ -44,7 +45,21 @@ export const Root = ({
4445
employeeUuids: memoizedEmployeeId,
4546
})
4647

47-
const { mutateAsync: updatePayroll, isPending } = usePayrollsUpdateMutation()
48+
const { mutateAsync: baseUpdatePayroll } = usePayrollsUpdateMutation()
49+
50+
const { mutateAsync: updatePayroll, isPending } = useBatchedMutation(
51+
async (batch: PayrollUpdateEmployeeCompensations[]) => {
52+
const result = await baseUpdatePayroll({
53+
request: {
54+
companyId,
55+
payrollId,
56+
payrollUpdate: { employeeCompensations: batch },
57+
},
58+
})
59+
return result.payrollPrepared!
60+
},
61+
{ batchSize: 100 },
62+
)
4863

4964
const employee = employeeData.employee!
5065
const employeeCompensation = preparedPayroll?.employeeCompensations?.at(0)
@@ -64,18 +79,10 @@ export const Root = ({
6479
const onSave = async (updatedCompensation: PayrollEmployeeCompensationsType) => {
6580
const transformedCompensation = transformEmployeeCompensation(updatedCompensation)
6681
await baseSubmitHandler(null, async () => {
67-
const result = await updatePayroll({
68-
request: {
69-
companyId,
70-
payrollId,
71-
payrollUpdate: {
72-
employeeCompensations: [transformedCompensation],
73-
},
74-
},
75-
})
82+
const [result] = await updatePayroll([transformedCompensation])
7683

7784
onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SAVED, {
78-
payrollPrepared: result.payrollPrepared,
85+
payrollPrepared: result,
7986
employee,
8087
})
8188
})

0 commit comments

Comments
 (0)