Skip to content
Merged
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
3 changes: 0 additions & 3 deletions docs/reference/Translations/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5074,9 +5074,6 @@ Translation keys for the `Payroll.PayrollOverview` i18n namespace.
| Property | Default value |
| ------ | ------ |
| <a id="property-payrollpayrolloverviewalerts"></a> `alerts` | |
| `alerts.checkPaymentWarning_one` | `"You noted {{count}} employee who should be paid by check."` |
| `alerts.checkPaymentWarning_other` | `"You noted {{count}} employees who should be paid by check."` |
| `alerts.checkPaymentWarningDescription` | `"Employees with this payment method will need their checks delivered to them."` |
| `alerts.directDepositDeadline` | `"To pay your employees with direct deposit by {{payDate}}, you'll need to run payroll by {{time}} on {{date}}"` |
| `alerts.payrollNotCalculated` | `"Payroll is not calculated"` |
| `alerts.payrollProcessedMessage` | `"{{amount}} will be debited on {{date}}. Make sure you have these funds available."` |
Expand Down
7 changes: 7 additions & 0 deletions docs/reference/payroll/blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,13 @@ _Inherits `children`, `className`, `defaultValues`, `FallbackComponent`, `Loader
| `runPayroll/receipt/get` | User requested the payroll receipt | `{ payrollId }` |
| `runPayroll/pdfPaystub/viewed` | User opened an employee's paystub PDF | `{ employeeId }` |
| `payroll/wire/form/done` | Wire-in details were confirmed via the embedded wire form | Submit wire-in response |
| `payroll/printChecks/start` | User opened the print-checks modal from the embedded print-checks banner | — |
| `payroll/printChecks/generate/start` | User submitted the print-checks form | — |
| `payroll/printChecks/generate/succeeded` | Printable checks finished generating | `{ documentUrl }` |
| `payroll/printChecks/generate/failed` | The print-checks request was rejected or generation failed | `{ errorMessage }` |
| `payroll/printChecks/retry` | User retried after a failed check generation | — |
| `payroll/printChecks/cancel` | User cancelled the print-checks form | — |
| `payroll/printChecks/close` | User closed the print-checks failure or summary screen | — |

<br />

Expand Down
109 changes: 109 additions & 0 deletions src/components/Payroll/PayrollOverview/PayrollOverview.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1357,3 +1357,112 @@ export const WithSkippedEmployee = () => {
/>
)
}

const checkPaymentPayrollData = {
payrollDeadline: new Date('2025-09-24T23:00:00.000Z'),
checkDate: '2025-09-26',
processedDate: null,
calculatedAt: new Date('2025-09-15T16:25:07.000Z'),
uuid: 'payroll-uuid',
payrollUuid: 'payroll-uuid',
companyUuid: 'company-uuid',
offCycle: false,
external: false,
payPeriod: {
startDate: '2025-09-12',
endDate: '2025-09-18',
payScheduleUuid: 'schedule-uuid',
},
totals: {
companyDebit: '5000.00',
netPayDebit: '4000.00',
taxDebit: '1000.00',
reimbursementDebit: '0.00',
childSupportDebit: '0.00',
reimbursements: '0.00',
netPay: '4000.00',
grossPay: '5000.00',
employeeBonuses: '0.00',
employeeCommissions: '0.00',
employeeCashTips: '0.00',
employeePaycheckTips: '0.00',
additionalEarnings: '0.00',
ownersDraw: '0.00',
checkAmount: '1000.00',
employerTaxes: '500.00',
employeeTaxes: '500.00',
benefits: '0.00',
employeeBenefitsDeductions: '0.00',
imputedPay: '0.00',
deferredPayrollTaxes: '0.00',
otherDeductions: '0.00',
},
companyTaxes: [],
createdAt: new Date('2025-09-15T16:19:04.000Z'),
submissionBlockers: [],
partnerOwnedDisbursement: false,
employeeCompensations: [
{
employeeUuid: 'emp-check-1',
firstName: 'Isaiah',
lastName: 'Berlin',
excluded: false,
version: 'v1',
grossPay: '4000',
netPay: '3200',
checkAmount: '3200',
paymentMethod: 'Check' as const,
memo: null,
fixedCompensations: [],
hourlyCompensations: [
{
name: 'Regular Hours',
hours: '40.000',
amount: '4000.0',
jobUuid: 'job-1',
compensationMultiplier: 1,
flsaStatus: 'Nonexempt',
},
],
paidTimeOff: [],
taxes: [
{ name: 'Federal Income Tax', employer: false, amount: '80' },
{ name: 'Federal Income Tax', employer: true, amount: '160' },
],
benefits: [],
deductions: [],
},
],
}

export const WithCheckPaymentEmployeeUnprocessed = () => {
return (
<PayrollOverviewPresentation
onEdit={fn().mockName('edit')}
onSubmit={fn().mockName('submit')}
taxes={{ 'Federal Income Tax': { employee: 80, employer: 160 } }}
isProcessed={false}
status={PayrollOverviewStatus.Viewing}
onCancel={fn().mockName('cancel')}
onPayrollReceipt={fn().mockName('payrollReceipt')}
onPaystubDownload={fn().mockName('paystubDownload')}
payrollData={{ ...checkPaymentPayrollData, processed: false }}
/>
)
}

export const WithCheckPaymentEmployeeProcessed = () => {
return (
<PayrollOverviewPresentation
onEdit={fn().mockName('edit')}
onSubmit={fn().mockName('submit')}
taxes={{ 'Federal Income Tax': { employee: 80, employer: 160 } }}
isProcessed
status={PayrollOverviewStatus.Viewing}
onCancel={fn().mockName('cancel')}
onPayrollReceipt={fn().mockName('payrollReceipt')}
onPaystubDownload={fn().mockName('paystubDownload')}
payrollData={{ ...checkPaymentPayrollData, processed: true }}
/>
)
}
58 changes: 58 additions & 0 deletions src/components/Payroll/PayrollOverview/PayrollOverview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,61 @@ describe('PayrollOverview calculatedAt guard', () => {
expect(screen.queryByText(/Review payroll/i)).toBeNull()
})
})

describe('PayrollOverview print checks modal', () => {
beforeEach(() => {
vi.clearAllMocks()
mockPayrollData = {
...basePayrollData,
employeeCompensations: [
{
employeeUuid: 'emp-check-1',
firstName: 'Isaiah',
lastName: 'Berlin',
excluded: false,
version: 'v1',
grossPay: '4000',
netPay: '3200',
checkAmount: '3200',
paymentMethod: 'Check',
memo: null,
fixedCompensations: [],
hourlyCompensations: [],
paidTimeOff: [],
taxes: [],
benefits: [],
deductions: [],
},
],
}
mockIsFetching = false
})

it('hides the View and print checks button until the payroll is processed', async () => {
mockPayrollData = { ...mockPayrollData, processed: false }

renderWithProviders(
<PayrollOverview companyId="company-uuid" payrollId="payroll-uuid" onEvent={vi.fn()} />,
)

expect(await screen.findByText(/noted 1 employee/i)).toBeInTheDocument()
expect(screen.queryByRole('button', { name: 'View and print checks' })).toBeNull()
})

it('opens the print checks modal from the alert once the payroll is processed', async () => {
const user = userEvent.setup()
mockPayrollData = {
...mockPayrollData,
processed: true,
processingRequest: { status: 'submit_success', errors: [] },
}

renderWithProviders(
<PayrollOverview companyId="company-uuid" payrollId="payroll-uuid" onEvent={vi.fn()} />,
)

await user.click(await screen.findByRole('button', { name: 'View and print checks' }))

expect(await screen.findByText('Choose check stock')).toBeInTheDocument()
})
})
13 changes: 13 additions & 0 deletions src/components/Payroll/PayrollOverview/PayrollOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
type ConfirmWireDetailsComponentType,
} from '../ConfirmWireDetails/ConfirmWireDetails'
import { canCancelPayroll } from '../helpers'
import { PrintChecks } from '../PrintChecks/PrintChecks'
import { PayrollOverviewPresentation } from './PayrollOverviewPresentation'
import { PayrollOverviewStatus } from './PayrollOverviewTypes'
import { useCompanyPaymentSpeed } from '@/hooks/useCompanyPaymentSpeed'
Expand Down Expand Up @@ -109,6 +110,13 @@ const findWireInRequestUuid = (
* | `runPayroll/receipt/get` | User requested the payroll receipt | `{ payrollId }` |
* | `runPayroll/pdfPaystub/viewed` | User opened an employee's paystub PDF | `{ employeeId }` |
* | `payroll/wire/form/done` | Wire-in details were confirmed via the embedded wire form | Submit wire-in response |
* | `payroll/printChecks/start` | User opened the print-checks modal from the embedded print-checks banner | — |
* | `payroll/printChecks/generate/start` | User submitted the print-checks form | — |
* | `payroll/printChecks/generate/succeeded` | Printable checks finished generating | `{ documentUrl }` |
* | `payroll/printChecks/generate/failed` | The print-checks request was rejected or generation failed | `{ errorMessage }` |
* | `payroll/printChecks/retry` | User retried after a failed check generation | — |
* | `payroll/printChecks/cancel` | User cancelled the print-checks form | — |
* | `payroll/printChecks/close` | User closed the print-checks failure or summary screen | — |
*
* @param props - See {@link PayrollOverviewProps}.
* @returns The payroll overview surface.
Expand Down Expand Up @@ -196,6 +204,10 @@ const Root = ({
/>
)

const printChecksBanner = (
<PrintChecks companyId={companyId} payrollId={payrollId} onEvent={onEvent} />
)

useEffect(() => {
if (wireInRequest?.status === 'pending_review' && !showWireDetailsConfirmation) {
setShowWireDetailsConfirmation(true)
Expand Down Expand Up @@ -436,6 +448,7 @@ const Root = ({
setSelectedUnblockOptions(prev => ({ ...prev, [blockerType]: value }))
}}
wireInConfirmationRequest={wireInConfirmationRequest}
printChecksBanner={printChecksBanner}
withReimbursements={withReimbursements}
paymentSpeed={paymentSpeed}
pagination={pagination}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
compensationTypeLabels,
FlsaStatus,
PAYROLL_RESOLVABLE_SUBMISSION_BLOCKER_TYPES,
PAYMENT_METHODS,
} from '@/shared/constants'
import type { PaginationControlProps } from '@/components/Common/PaginationControl/PaginationControlTypes'
import DownloadIcon from '@/assets/icons/download-cloud.svg?react'
Expand All @@ -48,6 +47,7 @@ interface PayrollOverviewProps {
submissionBlockers?: PayrollSubmissionBlockerType[]
selectedUnblockOptions?: Record<string, string>
wireInConfirmationRequest?: React.ReactNode
printChecksBanner?: React.ReactNode
pagination?: PaginationControlProps
onEdit: () => void
onSubmit: () => void
Expand Down Expand Up @@ -87,6 +87,7 @@ export const PayrollOverviewPresentation = ({
selectedUnblockOptions = {},
onUnblockOptionChange,
wireInConfirmationRequest,
printChecksBanner,
withReimbursements = true,
paymentSpeed,
pagination,
Expand Down Expand Up @@ -212,12 +213,6 @@ export const PayrollOverviewPresentation = ({
)
}

const checkPaymentsCount =
payrollData.employeeCompensations?.reduce(
(acc, comp) =>
!comp.excluded && comp.paymentMethod === PAYMENT_METHODS.check ? acc + 1 : acc,
0,
) ?? 0
const companyPaysColumns: Array<{
key: string
title: string
Expand Down Expand Up @@ -780,14 +775,7 @@ export const PayrollOverviewPresentation = ({
data={[{}]}
/>
)}
{checkPaymentsCount > 0 && (
<Alert
status="warning"
label={t('alerts.checkPaymentWarning', { count: checkPaymentsCount })}
>
{t('alerts.checkPaymentWarningDescription')}
</Alert>
)}
{printChecksBanner}
<Tabs
onSelectionChange={setSelectedTab}
selectedId={selectedTab}
Expand Down
3 changes: 0 additions & 3 deletions src/i18n/en/Payroll.PayrollOverview.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
"payrollNotCalculated": "Payroll is not calculated",
"directDepositDeadline": "To pay your employees with direct deposit by {{payDate}}, you'll need to run payroll by {{time}} on {{date}}",
"paystubPdfError": "There was an issue generating the paystub PDF. Please try again later.",
"checkPaymentWarning_one": "You noted {{count}} employee who should be paid by check.",
"checkPaymentWarning_other": "You noted {{count}} employees who should be paid by check.",
"checkPaymentWarningDescription": "Employees with this payment method will need their checks delivered to them.",
"payrollProcessedTitle": "Payroll submitted",
"payrollProcessedMessage": "{{amount}} will be debited on {{date}}. Make sure you have these funds available.",
"payrollProcessingFailedTitle": "There was an error submitting payroll",
Expand Down
6 changes: 0 additions & 6 deletions src/i18n/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7430,12 +7430,6 @@ export namespace Translations {
directDepositDeadline: string
/** @defaultValue `"There was an issue generating the paystub PDF. Please try again later."` */
paystubPdfError: string
/** @defaultValue `"You noted {{count}} employee who should be paid by check."` */
checkPaymentWarning_one: string
/** @defaultValue `"You noted {{count}} employees who should be paid by check."` */
checkPaymentWarning_other: string
/** @defaultValue `"Employees with this payment method will need their checks delivered to them."` */
checkPaymentWarningDescription: string
/** @defaultValue `"Payroll submitted"` */
payrollProcessedTitle: string
/** @defaultValue `"{{amount}} will be debited on {{date}}. Make sure you have these funds available."` */
Expand Down
Loading