Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,58 @@ describe('PayrollEditEmployeePresentation', () => {
}),
)
})

// Clearing the field used to omit the entry entirely, so the API kept the previously
// saved amount: the box looked empty while the old value survived the save (SDK-1284).
// Clearing now behaves exactly like typing 0, as in the test above.
it('zeroes an existing compensation when its field is cleared', async () => {
const user = userEvent.setup()
const onSave = vi.fn()

renderWithProviders(
<PayrollEditEmployeePresentation {...defaultPropsWithAdditionalEarnings} onSave={onSave} />,
)

// findBy, not getBy: the labels are translated, so a getBy here only passes when an
// earlier test in the file has already warmed the i18n namespace.
const bonusInput = await screen.findByLabelText('Bonus')
await user.clear(bonusInput)

const saveButton = screen.getByRole('button', { name: /save/i })
await user.click(saveButton)

expect(onSave).toHaveBeenCalledWith(
expect.objectContaining({
fixedCompensations: expect.arrayContaining([
expect.objectContaining({ name: 'Bonus', amount: '0', jobUuid: 'job-1' }),
expect.objectContaining({ name: 'Commission', amount: '50.00', jobUuid: 'job-1' }),
]),
}),
)
})

it('still omits an earning type that never had a saved amount', async () => {
const user = userEvent.setup()
const onSave = vi.fn()

renderWithProviders(
<PayrollEditEmployeePresentation {...defaultPropsWithAdditionalEarnings} onSave={onSave} />,
)

// 'Paycheck tips' is an available type with no saved compensation, so there is
// nothing to zero out and it must stay out of the payload.
const tipsInput = await screen.findByLabelText('Paycheck tips')
await user.type(tipsInput, '10')
await user.clear(tipsInput)

const saveButton = screen.getByRole('button', { name: /save/i })
await user.click(saveButton)

const saved = onSave.mock.calls[0]![0] as PayrollEmployeeCompensationsType
expect(saved.fixedCompensations?.map(compensation => compensation.name)).not.toContain(
'Paycheck Tips',
)
})
})

describe('Payment Method', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,25 @@ const buildCompensationFromFormData = (
fixedCompensation.name?.toLowerCase() === fixedCompensationName.toLowerCase(),
)

if (formAmount !== undefined && formAmount !== '') {
// Clearing the field means "no additional earning". For an entry that already has a
// saved amount we have to send an explicit 0: omitting it leaves the previously saved
// value in place server-side, so the box looked empty while the old amount survived
// the save (SDK-1284). This makes clearing behave exactly like typing 0. An entry with
// no saved compensation stays omitted -- there is nothing to zero out.
const resolvedAmount = formAmount === '' && existingFixedCompensation ? '0' : formAmount

if (resolvedAmount !== undefined && resolvedAmount !== '') {
if (existingFixedCompensation) {
updatedFixedCompensations.push({
name: existingFixedCompensation.name,
jobUuid: existingFixedCompensation.jobUuid,
amount: formAmount,
amount: resolvedAmount,
})
} else if (parseFloat(formAmount) !== 0) {
} else if (parseFloat(resolvedAmount) !== 0) {
updatedFixedCompensations.push({
name: fixedCompensationName,
jobUuid: primaryJobUuid,
amount: formAmount,
amount: resolvedAmount,
})
}
}
Expand Down
Loading