@gusto/embedded-react-sdk 0.55.3 → 0.55.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/dist/components/Common/DataView/DataCards/DataCards.d.ts +2 -1
- package/dist/components/Common/DataView/DataCards/DataCards.js +63 -54
- package/dist/components/Common/DataView/DataCards/DataCards.js.map +1 -1
- package/dist/components/Common/DataView/DataCards/DataCards.module.scss.js +14 -12
- package/dist/components/Common/DataView/DataCards/DataCards.module.scss.js.map +1 -1
- package/dist/components/Common/DataView/DataTable/DataTable.d.ts +2 -1
- package/dist/components/Common/DataView/DataTable/DataTable.js +75 -66
- package/dist/components/Common/DataView/DataTable/DataTable.js.map +1 -1
- package/dist/components/Common/DataView/DataTable/DataTable.module.scss.js +8 -4
- package/dist/components/Common/DataView/DataTable/DataTable.module.scss.js.map +1 -1
- package/dist/components/Common/DataView/DataView.js +18 -17
- package/dist/components/Common/DataView/DataView.js.map +1 -1
- package/dist/components/Company/Locations/LocationsList/List.js +27 -25
- package/dist/components/Company/Locations/LocationsList/List.js.map +1 -1
- package/dist/components/Company/Locations/LocationsList/LocationsList.js +41 -36
- package/dist/components/Company/Locations/LocationsList/LocationsList.js.map +1 -1
- package/dist/components/Company/Locations/LocationsList/useLocationsList.d.ts +1 -0
- package/dist/components/Company/Locations/LocationsList/useLocationsList.js.map +1 -1
- package/dist/components/Company/StateTaxes/StateTaxesForm/Form.d.ts +9 -2
- package/dist/components/Company/StateTaxes/StateTaxesForm/Form.js +19 -18
- package/dist/components/Company/StateTaxes/StateTaxesForm/Form.js.map +1 -1
- package/dist/components/Company/StateTaxes/StateTaxesForm/StateTaxesForm.js +63 -62
- package/dist/components/Company/StateTaxes/StateTaxesForm/StateTaxesForm.js.map +1 -1
- package/dist/components/Company/StateTaxes/TaxRateManagement/AddTaxRateDialog.js +69 -65
- package/dist/components/Company/StateTaxes/TaxRateManagement/AddTaxRateDialog.js.map +1 -1
- package/dist/components/Company/StateTaxes/TaxRateManagement/toHistoryRows.js +30 -23
- package/dist/components/Company/StateTaxes/TaxRateManagement/toHistoryRows.js.map +1 -1
- package/dist/components/Company/StateTaxes/shared/RequirementFields.d.ts +8 -4
- package/dist/components/Company/StateTaxes/shared/RequirementFields.js +13 -12
- package/dist/components/Company/StateTaxes/shared/RequirementFields.js.map +1 -1
- package/dist/components/Company/StateTaxes/shared/prepareRequirements.d.ts +29 -0
- package/dist/components/Company/StateTaxes/shared/prepareRequirements.js +24 -0
- package/dist/components/Company/StateTaxes/shared/prepareRequirements.js.map +1 -0
- package/dist/components/Company/StateTaxes/shared/prepareRequirements.test.d.ts +1 -0
- package/dist/components/Contractor/Payments/PaymentsList/PaymentsList.js +68 -55
- package/dist/components/Contractor/Payments/PaymentsList/PaymentsList.js.map +1 -1
- package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.js +36 -35
- package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.js.map +1 -1
- package/dist/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.js +84 -96
- package/dist/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.js.map +1 -1
- package/dist/components/Flow/Flow.js +22 -22
- package/dist/components/Flow/Flow.js.map +1 -1
- package/dist/components/Flow/useFlow.js +3 -3
- package/dist/components/InformationRequests/InformationRequests.d.ts +1 -1
- package/dist/components/InformationRequests/InformationRequests.js +66 -52
- package/dist/components/InformationRequests/InformationRequests.js.map +1 -1
- package/dist/components/Payroll/OffCycleCreation/OffCycleCreation.js +52 -50
- package/dist/components/Payroll/OffCycleCreation/OffCycleCreation.js.map +1 -1
- package/dist/components/Payroll/OffCycleCreation/OffCycleCreationPresentation.d.ts +1 -1
- package/dist/components/Payroll/OffCycleCreation/OffCycleCreationPresentation.js +86 -67
- package/dist/components/Payroll/OffCycleCreation/OffCycleCreationPresentation.js.map +1 -1
- package/dist/components/Payroll/OffCycleCreation/OffCycleCreationTypes.d.ts +4 -0
- package/dist/components/Payroll/OffCycleDeductionsSetting/OffCycleDeductionsSetting.d.ts +1 -1
- package/dist/components/Payroll/OffCycleDeductionsSetting/OffCycleDeductionsSetting.js +26 -21
- package/dist/components/Payroll/OffCycleDeductionsSetting/OffCycleDeductionsSetting.js.map +1 -1
- package/dist/components/Payroll/OffCyclePayPeriodDateForm/OffCyclePayPeriodDateFormPresentation.d.ts +8 -1
- package/dist/components/Payroll/OffCyclePayPeriodDateForm/OffCyclePayPeriodDateFormPresentation.js +29 -17
- package/dist/components/Payroll/OffCyclePayPeriodDateForm/OffCyclePayPeriodDateFormPresentation.js.map +1 -1
- package/dist/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.js +21 -18
- package/dist/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.js.map +1 -1
- package/dist/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.module.scss.js +9 -7
- package/dist/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.module.scss.js.map +1 -1
- package/dist/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTableTypes.d.ts +2 -0
- package/dist/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTableTypes.js.map +1 -1
- package/dist/components/Payroll/PayrollConfiguration/PayrollConfiguration.js +193 -191
- package/dist/components/Payroll/PayrollConfiguration/PayrollConfiguration.js.map +1 -1
- package/dist/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.d.ts +3 -2
- package/dist/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.js +31 -31
- package/dist/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.js.map +1 -1
- package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.js +254 -243
- package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.js.map +1 -1
- package/dist/components/Payroll/PayrollHistory/PayrollHistory.js +83 -76
- package/dist/components/Payroll/PayrollHistory/PayrollHistory.js.map +1 -1
- package/dist/components/Payroll/PayrollHistory/PayrollHistoryPresentation.js +23 -22
- package/dist/components/Payroll/PayrollHistory/PayrollHistoryPresentation.js.map +1 -1
- package/dist/components/Payroll/PayrollList/PayrollList.js +108 -97
- package/dist/components/Payroll/PayrollList/PayrollList.js.map +1 -1
- package/dist/components/Payroll/PayrollList/PayrollListPresentation.js +38 -37
- package/dist/components/Payroll/PayrollList/PayrollListPresentation.js.map +1 -1
- package/dist/components/Payroll/PayrollOverview/PayrollOverview.js +176 -167
- package/dist/components/Payroll/PayrollOverview/PayrollOverview.js.map +1 -1
- package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.d.ts +2 -1
- package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.js +173 -164
- package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.js.map +1 -1
- package/dist/helpers/openPdfInNewTab.d.ts +15 -0
- package/dist/helpers/openPdfInNewTab.js +28 -0
- package/dist/helpers/openPdfInNewTab.js.map +1 -0
- package/dist/i18n/en/Company.StateTaxes.json.js +1 -1
- package/dist/i18n/en/Payroll.OffCycleCreation.json.js +11 -9
- package/dist/i18n/en/Payroll.OffCycleCreation.json.js.map +1 -1
- package/dist/i18n/en/Payroll.OffCycleTaxWithholding.json.js +7 -7
- package/dist/i18n/en/Payroll.PayrollEditEmployee.json.js +29 -27
- package/dist/i18n/en/Payroll.PayrollEditEmployee.json.js.map +1 -1
- package/dist/i18n/en/Payroll.PayrollOverview.json.js +43 -41
- package/dist/i18n/en/Payroll.PayrollOverview.json.js.map +1 -1
- package/dist/i18n/types.d.ts +20 -0
- package/dist/style.css +1 -1
- package/package.json +17 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PayrollConfiguration.js","sources":["../../../../src/components/Payroll/PayrollConfiguration/PayrollConfiguration.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { usePayrollsGetSuspense } from '@gusto/embedded-api/react-query/payrollsGet'\nimport { payrollsCalculate } from '@gusto/embedded-api/funcs/payrollsCalculate'\nimport { useGustoEmbeddedContext } from '@gusto/embedded-api/react-query/_context'\nimport type { PayrollProcessingRequest } from '@gusto/embedded-api/models/components/payrollprocessingrequest'\nimport { PayrollProcessingRequestStatus } from '@gusto/embedded-api/models/components/payrollprocessingrequest'\nimport type { Employee } from '@gusto/embedded-api/models/components/employee'\nimport { useTranslation } from 'react-i18next'\nimport { usePayrollsUpdateMutation } from '@gusto/embedded-api/react-query/payrollsUpdate'\nimport { usePayrollsCalculateGrossUpMutation } from '@gusto/embedded-api/react-query/payrollsCalculateGrossUp'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollUpdateEmployeeCompensations } from '@gusto/embedded-api/models/components/payrollupdate'\nimport { usePayrollsGetBlockersSuspense } from '@gusto/embedded-api/react-query/payrollsGetBlockers'\nimport { payrollSubmitHandler, type ApiPayrollBlocker } from '../PayrollBlocker/payrollHelpers'\nimport { GrossUpModal } from '../GrossUpModal'\nimport { PayrollOverview } from '../PayrollOverview/PayrollOverview'\nimport type { PayrollFlowAlert } from '../PayrollFlow/PayrollFlowComponents'\nimport { PayrollConfigurationPresentation } from './PayrollConfigurationPresentation'\nimport { usePayrollConfigurationData } from './usePayrollConfigurationData'\nimport { getGrossUpTargetCompensationName, isGrossUpEligible } from './grossUpHelpers'\nimport type { BaseComponentInterface } from '@/components/Base/Base'\nimport { BaseComponent } from '@/components/Base/Base'\nimport { componentEvents, type EventType } from '@/shared/constants'\nimport { useComponentDictionary, useI18n } from '@/i18n'\nimport { useBase } from '@/components/Base'\nimport { useDateFormatter } from '@/hooks/useDateFormatter'\nimport { SDKInternalError } from '@/types/sdkError'\nimport { API_QUERY_NAMESPACE } from '@/contexts/ApiProvider/apiVersion'\n\nconst isCalculatingStatus = (processingRequest?: PayrollProcessingRequest | null) =>\n processingRequest?.status === PayrollProcessingRequestStatus.Calculating\n\nconst isCalculatedStatus = (\n processingRequest?: PayrollProcessingRequest | null,\n calculatedAt?: Date | null,\n) =>\n calculatedAt != null &&\n (processingRequest?.status === PayrollProcessingRequestStatus.CalculateSuccess ||\n processingRequest == null)\n\n/**\n * Props for {@link PayrollConfiguration}.\n *\n * @public\n */\nexport interface PayrollConfigurationProps extends BaseComponentInterface<'Payroll.PayrollConfiguration'> {\n /** The associated company identifier. */\n companyId: string\n /** The associated payroll identifier. */\n payrollId: string\n /** Optional alert components to render above the configuration content. */\n alerts?: ReactNode\n /** Whether to show the reimbursements column in the compensation table. Defaults to `true`. */\n withReimbursements?: boolean\n}\n\n/**\n * Handles the configuration phase of payroll processing, allowing users to review and modify employee compensation before calculating the payroll.\n *\n * @remarks\n * If the payroll turns out to already be processed (e.g. another actor submitted it while this\n * screen was open), this component emits `runPayroll/alreadyProcessed` and then renders\n * {@link PayrollOverview} in its place — the read-only breakdown with the gated \"Cancel payroll\"\n * action — instead of the configuration table. Events from that delegated view (e.g.\n * `runPayroll/cancelled`) are emitted through this component's own `onEvent`.\n *\n * Emits the following events:\n *\n * @events\n * | Event | Description | Data |\n * | ----- | ----------- | ---- |\n * | `runPayroll/employee/edit` | An employee row is selected for editing | `{ employeeId, firstName, lastName }` |\n * | `runPayroll/employee/skip` | An employee is skipped or unskipped for this payroll | `{ employeeId }` |\n * | `runPayroll/employee/saved` | Employee compensation changes are persisted | `{ payrollPrepared }` |\n * | `runPayroll/calculated` | Payroll calculation completes successfully | `{ payrollId, alert, payPeriod }` |\n * | `runPayroll/alreadyProcessed` | The payroll turns out to already be processed while configuring it | `{ payrollId, alert, payPeriod }` |\n * | `runPayroll/processingFailed` | Payroll calculation fails or times out | — |\n * | `runPayroll/blockers/viewAll` | The \"view all blockers\" affordance is selected | — |\n * | `runPayroll/grossUp/selected` | The set-net-earnings menu item is selected for an employee | `{ employeeUuid }` |\n * | `runPayroll/grossUp/calculated` | A gross-up amount is calculated from a target net pay | `{ grossUp, netPay, employeeUuid }` |\n *\n * @param props - See {@link PayrollConfigurationProps}.\n * @returns The payroll configuration screen.\n * @public\n */\nexport function PayrollConfiguration(props: PayrollConfigurationProps) {\n return (\n <BaseComponent {...props}>\n <Root {...props}>{props.children}</Root>\n </BaseComponent>\n )\n}\n\nconst Root = ({\n onEvent,\n companyId,\n payrollId,\n dictionary,\n alerts,\n withReimbursements = true,\n}: PayrollConfigurationProps) => {\n useComponentDictionary('Payroll.PayrollConfiguration', dictionary)\n useI18n('Payroll.PayrollConfiguration')\n const { t } = useTranslation('Payroll.PayrollConfiguration')\n const { baseSubmitHandler } = useBase()\n const dateFormatter = useDateFormatter()\n\n const [isPolling, setIsPolling] = useState(false)\n const [isCalculatingPayroll, setIsCalculatingPayroll] = useState(false)\n const previousCalculatedAtRef = useRef<number | null>(null)\n const gustoClient = useGustoEmbeddedContext()\n const queryClient = useQueryClient()\n\n const { data: payrollData } = usePayrollsGetSuspense(\n {\n companyId,\n payrollId,\n include: ['taxes', 'benefits', 'deductions', 'payroll_status_meta'],\n },\n { refetchInterval: isPolling ? 5_000 : false },\n )\n\n const excludedEmployeeUuids = useMemo(\n () =>\n payrollData.payrollShow?.employeeCompensations\n ?.filter(comp => comp.excluded)\n .map(comp => comp.employeeUuid!)\n .filter(Boolean) ?? [],\n [payrollData.payrollShow?.employeeCompensations],\n )\n\n const {\n employeeDetails,\n employeeCompensations,\n paySchedule,\n payPeriod,\n payrollCategory,\n pagination,\n isLoading,\n isAlreadyProcessed,\n refetch,\n } = usePayrollConfigurationData({\n companyId,\n payrollId,\n isCalculating: isPolling || isCalculatingPayroll,\n excludedEmployeeUuids,\n })\n\n const alreadyProcessedAlert: PayrollFlowAlert = useMemo(\n () => ({\n type: 'error',\n title: t('alerts.alreadyProcessed'),\n alertKey: 'alreadyProcessed',\n }),\n [t],\n )\n\n const hasFiredAlreadyProcessedRef = useRef(false)\n\n useEffect(() => {\n if (!isAlreadyProcessed) {\n hasFiredAlreadyProcessedRef.current = false\n return\n }\n if (hasFiredAlreadyProcessedRef.current) return\n hasFiredAlreadyProcessedRef.current = true\n onEvent(componentEvents.RUN_PAYROLL_ALREADY_PROCESSED, {\n payrollId,\n alert: alreadyProcessedAlert,\n payPeriod: payrollData.payrollShow?.payPeriod,\n })\n }, [\n isAlreadyProcessed,\n onEvent,\n payrollId,\n alreadyProcessedAlert,\n payrollData.payrollShow?.payPeriod,\n ])\n\n const { mutateAsync: updatePayroll, isPending: isUpdatingPayroll } = usePayrollsUpdateMutation()\n\n const { mutateAsync: calculateGrossUpMutation } = usePayrollsCalculateGrossUpMutation()\n\n const [grossUpEmployeeUuid, setGrossUpEmployeeUuid] = useState<string | null>(null)\n const [isGrossUpModalOpen, setIsGrossUpModalOpen] = useState(false)\n\n const grossUpEnabled = isGrossUpEligible(payrollCategory)\n const grossUpTargetCompensation = getGrossUpTargetCompensationName(payrollCategory)\n\n const onGrossUpSelect = (employeeUuid: string) => {\n setGrossUpEmployeeUuid(employeeUuid)\n setIsGrossUpModalOpen(true)\n onEvent(componentEvents.RUN_PAYROLL_GROSS_UP_SELECTED, { employeeUuid })\n }\n\n const onCalculateGrossUp = async (netPay: number): Promise<string | null> => {\n if (!grossUpEmployeeUuid) return null\n let grossUp: string | null = null\n\n await baseSubmitHandler(null, async () => {\n const result = await calculateGrossUpMutation({\n request: {\n payrollUuid: payrollId,\n payrollGrossUpRequest: {\n employeeUuid: grossUpEmployeeUuid,\n netPay: netPay.toString(),\n },\n },\n })\n\n grossUp = result.payrollGrossUpResponse?.grossUp ?? null\n\n if (grossUp) {\n onEvent(componentEvents.RUN_PAYROLL_GROSS_UP_CALCULATED, {\n grossUp,\n netPay,\n employeeUuid: grossUpEmployeeUuid,\n })\n }\n })\n\n return grossUp\n }\n\n const onGrossUpApply = async (grossAmount: string) => {\n if (!grossUpEmployeeUuid || !grossUpTargetCompensation) {\n throw new SDKInternalError(\n 'Unable to apply gross-up: missing employee or target compensation.',\n )\n }\n\n const employeeComp = employeeCompensations.find(ec => ec.employeeUuid === grossUpEmployeeUuid)\n if (!employeeComp) {\n throw new SDKInternalError('Unable to apply gross-up: employee compensation not found.')\n }\n\n const existingFixed = employeeComp.fixedCompensations ?? []\n const hasTargetCompensation = existingFixed.some(\n fc => fc.name?.toLowerCase() === grossUpTargetCompensation.toLowerCase(),\n )\n\n const updatedFixedCompensations = existingFixed.map(fc => ({\n name: fc.name,\n jobUuid: fc.jobUuid,\n amount:\n fc.name?.toLowerCase() === grossUpTargetCompensation.toLowerCase() ? grossAmount : '0',\n }))\n\n if (!hasTargetCompensation) {\n const primaryJobUuid =\n employeeComp.hourlyCompensations?.[0]?.jobUuid ?? existingFixed[0]?.jobUuid ?? ''\n updatedFixedCompensations.push({\n name: grossUpTargetCompensation,\n jobUuid: primaryJobUuid,\n amount: grossAmount,\n })\n }\n\n const updatedHourlyCompensations = (employeeComp.hourlyCompensations ?? []).map(hc => ({\n name: hc.name,\n jobUuid: hc.jobUuid,\n hours: '0',\n }))\n\n const updatedPaidTimeOff = (employeeComp.paidTimeOff ?? []).map(pto => ({\n name: pto.name,\n hours: '0',\n }))\n\n const transformedCompensation = transformEmployeeCompensation({\n ...employeeComp,\n fixedCompensations: updatedFixedCompensations,\n hourlyCompensations: updatedHourlyCompensations,\n paidTimeOff: updatedPaidTimeOff,\n })\n\n await baseSubmitHandler({}, async () => {\n const result = await updatePayroll({\n request: {\n companyId,\n payrollId,\n payrollUpdate: {\n employeeCompensations: [{ ...transformedCompensation, excluded: false }],\n },\n },\n })\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SAVED, {\n payrollPrepared: result.payrollPrepared,\n })\n await refetch()\n })\n\n setGrossUpEmployeeUuid(null)\n setIsGrossUpModalOpen(false)\n }\n\n const handleGrossUpApply = async (grossAmount: string) => {\n try {\n await onGrossUpApply(grossAmount)\n } catch {\n // Modal stays open; error is surfaced by baseSubmitHandler\n }\n }\n\n const { data: blockersData } = usePayrollsGetBlockersSuspense({\n companyUuid: companyId,\n })\n\n const payrollBlockerList = blockersData.payrollBlockers ?? []\n\n const blockersFromApi: ApiPayrollBlocker[] = payrollBlockerList.map(blocker => ({\n key: blocker.key,\n message: blocker.message,\n }))\n\n const [payrollBlockers, setPayrollBlockers] = useState(blockersFromApi)\n\n const onCalculatePayroll = async () => {\n setPayrollBlockers([])\n previousCalculatedAtRef.current = payrollData.payrollShow?.calculatedAt?.getTime() ?? null\n\n await baseSubmitHandler({}, async () => {\n const result = await payrollSubmitHandler(async () => {\n setIsCalculatingPayroll(true)\n try {\n const calcResult = await payrollsCalculate(gustoClient, {\n companyId,\n payrollId,\n })\n if (!calcResult.ok) {\n throw calcResult.error\n }\n // `payrollsCalculate` is a raw func, so it skips the global onSuccess\n // invalidation that mutation hooks get; invalidate here so cached payroll\n // reads (e.g. PayrollOverview's separate key) refetch fresh. SDK-1018.\n void queryClient.invalidateQueries({ queryKey: [API_QUERY_NAMESPACE] })\n setIsPolling(true)\n } finally {\n setIsCalculatingPayroll(false)\n }\n })\n\n if (!result.success && result.blockers.length > 0) {\n setPayrollBlockers(result.blockers)\n }\n })\n }\n\n const onEdit = (employee: Employee) => {\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_EDIT, {\n employeeId: employee.uuid,\n firstName: employee.firstName,\n lastName: employee.lastName,\n })\n }\n\n const transformEmployeeCompensation = (\n compensation: PayrollEmployeeCompensationsType,\n ): PayrollUpdateEmployeeCompensations => {\n const { paymentMethod } = compensation\n return {\n employeeUuid: compensation.employeeUuid,\n version: compensation.version,\n excluded: compensation.excluded,\n fixedCompensations: compensation.fixedCompensations,\n hourlyCompensations: compensation.hourlyCompensations,\n paidTimeOff: compensation.paidTimeOff,\n deductions: compensation.deductions,\n ...(paymentMethod && paymentMethod !== 'Historical' ? { paymentMethod } : {}),\n memo: compensation.memo || undefined,\n }\n }\n\n const onToggleExclude = async (employeeCompensation: PayrollEmployeeCompensationsType) => {\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SKIP, {\n employeeId: employeeCompensation.employeeUuid,\n })\n await baseSubmitHandler({}, async () => {\n const transformedCompensation = transformEmployeeCompensation(employeeCompensation)\n const result = await updatePayroll({\n request: {\n companyId,\n payrollId,\n payrollUpdate: {\n employeeCompensations: [\n { ...transformedCompensation, excluded: !transformedCompensation.excluded },\n ],\n },\n },\n })\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SAVED, {\n payrollPrepared: result.payrollPrepared,\n })\n await refetch()\n })\n }\n\n const onViewBlockers = () => {\n onEvent(componentEvents.RUN_PAYROLL_BLOCKERS_VIEW_ALL)\n }\n\n useEffect(() => {\n if (isCalculatingStatus(payrollData.payrollShow?.processingRequest) && !isPolling) {\n previousCalculatedAtRef.current = payrollData.payrollShow?.calculatedAt?.getTime() ?? null\n setIsPolling(true)\n }\n const currentCalculatedAt = payrollData.payrollShow?.calculatedAt\n const isNewCalculation = currentCalculatedAt?.getTime() !== previousCalculatedAtRef.current\n if (\n isPolling &&\n isNewCalculation &&\n isCalculatedStatus(payrollData.payrollShow?.processingRequest, currentCalculatedAt)\n ) {\n onEvent(componentEvents.RUN_PAYROLL_CALCULATED, {\n payrollId,\n alert: {\n type: 'success',\n title: t('alerts.progressSaved'),\n alertKey: 'progressSaved',\n },\n payPeriod: payrollData.payrollShow?.payPeriod,\n })\n setPayrollBlockers([])\n setIsPolling(false)\n }\n if (\n isPolling &&\n payrollData.payrollShow?.processingRequest?.status ===\n PayrollProcessingRequestStatus.ProcessingFailed\n ) {\n onEvent(componentEvents.RUN_PAYROLL_PROCESSING_FAILED)\n setIsPolling(false)\n }\n }, [\n payrollData.payrollShow?.processingRequest?.status,\n payrollData.payrollShow?.calculatedAt,\n isPolling,\n onEvent,\n t,\n payrollId,\n ])\n\n useEffect(() => {\n if (!isPolling) return\n\n const POLLING_TIMEOUT_MS = 3 * 60 * 1000\n const timeoutId = setTimeout(() => {\n onEvent(componentEvents.RUN_PAYROLL_PROCESSING_FAILED)\n setIsPolling(false)\n }, POLLING_TIMEOUT_MS)\n\n return () => {\n clearTimeout(timeoutId)\n }\n }, [isPolling, onEvent])\n\n const payrollAlert = (() => {\n const statusMeta = payrollData.payrollShow?.payrollStatusMeta\n\n const isLatePayroll =\n statusMeta?.payrollLate &&\n statusMeta.initialCheckDate &&\n statusMeta.expectedDebitTime &&\n statusMeta.expectedCheckDate\n\n if (isLatePayroll) {\n return {\n label: t('alerts.payrollLate', {\n initialCheckDate: dateFormatter.formatShortWithWeekday(statusMeta.initialCheckDate),\n }),\n content: t('alerts.payrollLateText', {\n ...dateFormatter.formatWithTime(statusMeta.expectedDebitTime),\n newCheckDate: dateFormatter.formatShortWithWeekday(statusMeta.expectedCheckDate),\n }),\n variant: 'warning' as const,\n }\n }\n\n const { payrollShow } = payrollData\n\n if (payrollShow?.checkDate && payrollShow.payrollDeadline) {\n return {\n label: t('alerts.directDepositDeadline', {\n payDate: dateFormatter.formatShortWithWeekday(payrollShow.checkDate),\n ...dateFormatter.formatWithTime(payrollShow.payrollDeadline),\n }),\n content: t('alerts.directDepositDeadlineText'),\n variant: 'info' as const,\n }\n }\n\n return undefined\n })()\n\n if (isAlreadyProcessed) {\n const onAlreadyProcessedOverviewEvent = (type: EventType, data?: unknown) => {\n if (type === componentEvents.RUN_PAYROLL_CANCELLED) {\n // Cancelling un-processes the payroll, making it editable again — re-run prepare so\n // this component drops back into the configuration table for the same payrollId.\n void refetch()\n }\n onEvent(type, data)\n }\n\n return (\n <PayrollOverview\n companyId={companyId}\n payrollId={payrollId}\n onEvent={onAlreadyProcessedOverviewEvent}\n withReimbursements={withReimbursements}\n alerts={[alreadyProcessedAlert]}\n />\n )\n }\n\n return (\n <>\n <PayrollConfigurationPresentation\n onCalculatePayroll={onCalculatePayroll}\n isCalculateDisabled={blockersFromApi.length > 0}\n onEdit={onEdit}\n onToggleExclude={onToggleExclude}\n onViewBlockers={onViewBlockers}\n employeeCompensations={employeeCompensations}\n employeeDetails={employeeDetails}\n payPeriod={payPeriod}\n paySchedule={paySchedule}\n payrollCategory={payrollCategory}\n alerts={alerts}\n payrollAlert={payrollAlert}\n isPending={isPolling || isLoading || isUpdatingPayroll || isCalculatingPayroll}\n isCalculating={isCalculatingPayroll || isPolling}\n payrollBlockers={payrollBlockers}\n pagination={pagination}\n withReimbursements={withReimbursements}\n grossUpEnabled={grossUpEnabled}\n onGrossUpSelect={onGrossUpSelect}\n />\n {grossUpEnabled && (\n <GrossUpModal\n isOpen={isGrossUpModalOpen}\n onCalculateGrossUp={onCalculateGrossUp}\n onApply={handleGrossUpApply}\n onCancel={() => {\n setIsGrossUpModalOpen(false)\n }}\n />\n )}\n </>\n )\n}\n"],"names":["isCalculatingStatus","processingRequest","PayrollProcessingRequestStatus","isCalculatedStatus","calculatedAt","PayrollConfiguration","props","jsx","BaseComponent","Root","onEvent","companyId","payrollId","dictionary","alerts","withReimbursements","useComponentDictionary","useI18n","t","useTranslation","baseSubmitHandler","useBase","dateFormatter","useDateFormatter","isPolling","setIsPolling","useState","isCalculatingPayroll","setIsCalculatingPayroll","previousCalculatedAtRef","useRef","gustoClient","useGustoEmbeddedContext","queryClient","useQueryClient","payrollData","usePayrollsGetSuspense","excludedEmployeeUuids","useMemo","comp","employeeDetails","employeeCompensations","paySchedule","payPeriod","payrollCategory","pagination","isLoading","isAlreadyProcessed","refetch","usePayrollConfigurationData","alreadyProcessedAlert","hasFiredAlreadyProcessedRef","useEffect","componentEvents","updatePayroll","isUpdatingPayroll","usePayrollsUpdateMutation","calculateGrossUpMutation","usePayrollsCalculateGrossUpMutation","grossUpEmployeeUuid","setGrossUpEmployeeUuid","isGrossUpModalOpen","setIsGrossUpModalOpen","grossUpEnabled","isGrossUpEligible","grossUpTargetCompensation","getGrossUpTargetCompensationName","onGrossUpSelect","employeeUuid","onCalculateGrossUp","netPay","grossUp","onGrossUpApply","grossAmount","SDKInternalError","employeeComp","ec","existingFixed","hasTargetCompensation","fc","updatedFixedCompensations","primaryJobUuid","updatedHourlyCompensations","hc","updatedPaidTimeOff","pto","transformedCompensation","transformEmployeeCompensation","result","handleGrossUpApply","blockersData","usePayrollsGetBlockersSuspense","blockersFromApi","blocker","payrollBlockers","setPayrollBlockers","onCalculatePayroll","payrollSubmitHandler","calcResult","payrollsCalculate","API_QUERY_NAMESPACE","onEdit","employee","compensation","paymentMethod","onToggleExclude","employeeCompensation","onViewBlockers","currentCalculatedAt","isNewCalculation","POLLING_TIMEOUT_MS","timeoutId","payrollAlert","statusMeta","payrollShow","PayrollOverview","type","data","jsxs","Fragment","PayrollConfigurationPresentation","GrossUpModal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PayrollConfiguration.js","sources":["../../../../src/components/Payroll/PayrollConfiguration/PayrollConfiguration.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport { usePayrollsGetSuspense } from '@gusto/embedded-api/react-query/payrollsGet'\nimport { payrollsCalculate } from '@gusto/embedded-api/funcs/payrollsCalculate'\nimport { useGustoEmbeddedContext } from '@gusto/embedded-api/react-query/_context'\nimport type { PayrollProcessingRequest } from '@gusto/embedded-api/models/components/payrollprocessingrequest'\nimport { PayrollProcessingRequestStatus } from '@gusto/embedded-api/models/components/payrollprocessingrequest'\nimport type { Employee } from '@gusto/embedded-api/models/components/employee'\nimport { useTranslation } from 'react-i18next'\nimport { usePayrollsUpdateMutation } from '@gusto/embedded-api/react-query/payrollsUpdate'\nimport { usePayrollsCalculateGrossUpMutation } from '@gusto/embedded-api/react-query/payrollsCalculateGrossUp'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollUpdateEmployeeCompensations } from '@gusto/embedded-api/models/components/payrollupdate'\nimport { usePayrollsGetBlockersSuspense } from '@gusto/embedded-api/react-query/payrollsGetBlockers'\nimport { payrollSubmitHandler, type ApiPayrollBlocker } from '../PayrollBlocker/payrollHelpers'\nimport { GrossUpModal } from '../GrossUpModal'\nimport { PayrollOverview } from '../PayrollOverview/PayrollOverview'\nimport type { PayrollFlowAlert } from '../PayrollFlow/PayrollFlowComponents'\nimport { PayrollConfigurationPresentation } from './PayrollConfigurationPresentation'\nimport { usePayrollConfigurationData } from './usePayrollConfigurationData'\nimport { getGrossUpTargetCompensationName, isGrossUpEligible } from './grossUpHelpers'\nimport type { BaseComponentInterface } from '@/components/Base/Base'\nimport { BaseComponent } from '@/components/Base/Base'\nimport { componentEvents, type EventType } from '@/shared/constants'\nimport { useComponentDictionary, useI18n } from '@/i18n'\nimport { useBase } from '@/components/Base'\nimport { useDateFormatter } from '@/hooks/useDateFormatter'\nimport { SDKInternalError } from '@/types/sdkError'\n\nconst isCalculatingStatus = (processingRequest?: PayrollProcessingRequest | null) =>\n processingRequest?.status === PayrollProcessingRequestStatus.Calculating\n\nconst isCalculatedStatus = (\n processingRequest?: PayrollProcessingRequest | null,\n calculatedAt?: Date | null,\n) =>\n calculatedAt != null &&\n (processingRequest?.status === PayrollProcessingRequestStatus.CalculateSuccess ||\n processingRequest == null)\n\n/**\n * Props for {@link PayrollConfiguration}.\n *\n * @public\n */\nexport interface PayrollConfigurationProps extends BaseComponentInterface<'Payroll.PayrollConfiguration'> {\n /** The associated company identifier. */\n companyId: string\n /** The associated payroll identifier. */\n payrollId: string\n /** Optional alert components to render above the configuration content. */\n alerts?: ReactNode\n /** Whether to show the reimbursements column in the compensation table. Defaults to `true`. */\n withReimbursements?: boolean\n}\n\n/**\n * Handles the configuration phase of payroll processing, allowing users to review and modify employee compensation before calculating the payroll.\n *\n * @remarks\n * If the payroll turns out to already be processed (e.g. another actor submitted it while this\n * screen was open), this component emits `runPayroll/alreadyProcessed` and then renders\n * {@link PayrollOverview} in its place — the read-only breakdown with the gated \"Cancel payroll\"\n * action — instead of the configuration table. Events from that delegated view (e.g.\n * `runPayroll/cancelled`) are emitted through this component's own `onEvent`.\n *\n * Emits the following events:\n *\n * @events\n * | Event | Description | Data |\n * | ----- | ----------- | ---- |\n * | `runPayroll/employee/edit` | An employee row is selected for editing | `{ employeeId, firstName, lastName }` |\n * | `runPayroll/employee/skip` | An employee is skipped or unskipped for this payroll | `{ employeeId }` |\n * | `runPayroll/employee/saved` | Employee compensation changes are persisted | `{ payrollPrepared }` |\n * | `runPayroll/calculated` | Payroll calculation completes successfully | `{ payrollId, alert, payPeriod }` |\n * | `runPayroll/alreadyProcessed` | The payroll turns out to already be processed while configuring it | `{ payrollId, alert, payPeriod }` |\n * | `runPayroll/processingFailed` | Payroll calculation fails or times out | — |\n * | `runPayroll/blockers/viewAll` | The \"view all blockers\" affordance is selected | — |\n * | `runPayroll/grossUp/selected` | The set-net-earnings menu item is selected for an employee | `{ employeeUuid }` |\n * | `runPayroll/grossUp/calculated` | A gross-up amount is calculated from a target net pay | `{ grossUp, netPay, employeeUuid }` |\n *\n * @param props - See {@link PayrollConfigurationProps}.\n * @returns The payroll configuration screen.\n * @public\n */\nexport function PayrollConfiguration(props: PayrollConfigurationProps) {\n return (\n <BaseComponent {...props}>\n <Root {...props}>{props.children}</Root>\n </BaseComponent>\n )\n}\n\nconst Root = ({\n onEvent,\n companyId,\n payrollId,\n dictionary,\n alerts,\n withReimbursements = true,\n}: PayrollConfigurationProps) => {\n useComponentDictionary('Payroll.PayrollConfiguration', dictionary)\n useI18n('Payroll.PayrollConfiguration')\n const { t } = useTranslation('Payroll.PayrollConfiguration')\n const { baseSubmitHandler } = useBase()\n const dateFormatter = useDateFormatter()\n\n const [isPolling, setIsPolling] = useState(false)\n const [isCalculatingPayroll, setIsCalculatingPayroll] = useState(false)\n const previousCalculatedAtRef = useRef<number | null>(null)\n // True once this screen has read a \"calculating\" status for the payroll, whether we started that\n // calc or someone else did. Calling prepare after that would wipe the result, so we use this to\n // keep prepare off.\n const hasSeenCalculatingRef = useRef(false)\n const gustoClient = useGustoEmbeddedContext()\n\n const { data: payrollData } = usePayrollsGetSuspense(\n {\n companyId,\n payrollId,\n include: ['taxes', 'benefits', 'deductions', 'payroll_status_meta'],\n },\n { refetchInterval: isPolling ? 5_000 : false },\n )\n\n const excludedEmployeeUuids = useMemo(\n () =>\n payrollData.payrollShow?.employeeCompensations\n ?.filter(comp => comp.excluded)\n .map(comp => comp.employeeUuid!)\n .filter(Boolean) ?? [],\n [payrollData.payrollShow?.employeeCompensations],\n )\n\n // Remember once we've seen it calculating.\n if (isCalculatingStatus(payrollData.payrollShow?.processingRequest)) {\n hasSeenCalculatingRef.current = true\n }\n\n // Show the loading state the whole time we're calculating, so a second tab shows the loader\n // instead of a blank table until it moves to the overview.\n const isCalculatingActive = isCalculatingPayroll || isPolling || hasSeenCalculatingRef.current\n\n const {\n employeeDetails,\n employeeCompensations,\n paySchedule,\n payPeriod,\n payrollCategory,\n pagination,\n isLoading,\n isAlreadyProcessed,\n refetch,\n } = usePayrollConfigurationData({\n companyId,\n payrollId,\n // Don't prepare while calculating, or once we've seen it calculate. If the payroll was already\n // calculated when we opened (e.g. clicking Edit), we do prepare so it can be edited.\n disablePrepare: isPolling || isCalculatingPayroll || hasSeenCalculatingRef.current,\n excludedEmployeeUuids,\n })\n\n const alreadyProcessedAlert: PayrollFlowAlert = useMemo(\n () => ({\n type: 'error',\n title: t('alerts.alreadyProcessed'),\n alertKey: 'alreadyProcessed',\n }),\n [t],\n )\n\n const hasFiredAlreadyProcessedRef = useRef(false)\n\n useEffect(() => {\n if (!isAlreadyProcessed) {\n hasFiredAlreadyProcessedRef.current = false\n return\n }\n if (hasFiredAlreadyProcessedRef.current) return\n hasFiredAlreadyProcessedRef.current = true\n onEvent(componentEvents.RUN_PAYROLL_ALREADY_PROCESSED, {\n payrollId,\n alert: alreadyProcessedAlert,\n payPeriod: payrollData.payrollShow?.payPeriod,\n })\n }, [\n isAlreadyProcessed,\n onEvent,\n payrollId,\n alreadyProcessedAlert,\n payrollData.payrollShow?.payPeriod,\n ])\n\n const { mutateAsync: updatePayroll, isPending: isUpdatingPayroll } = usePayrollsUpdateMutation()\n\n const { mutateAsync: calculateGrossUpMutation } = usePayrollsCalculateGrossUpMutation()\n\n const [grossUpEmployeeUuid, setGrossUpEmployeeUuid] = useState<string | null>(null)\n const [isGrossUpModalOpen, setIsGrossUpModalOpen] = useState(false)\n\n const grossUpEnabled = isGrossUpEligible(payrollCategory)\n const grossUpTargetCompensation = getGrossUpTargetCompensationName(payrollCategory)\n\n const onGrossUpSelect = (employeeUuid: string) => {\n setGrossUpEmployeeUuid(employeeUuid)\n setIsGrossUpModalOpen(true)\n onEvent(componentEvents.RUN_PAYROLL_GROSS_UP_SELECTED, { employeeUuid })\n }\n\n const onCalculateGrossUp = async (netPay: number): Promise<string | null> => {\n if (!grossUpEmployeeUuid) return null\n let grossUp: string | null = null\n\n await baseSubmitHandler(null, async () => {\n const result = await calculateGrossUpMutation({\n request: {\n payrollUuid: payrollId,\n payrollGrossUpRequest: {\n employeeUuid: grossUpEmployeeUuid,\n netPay: netPay.toString(),\n },\n },\n })\n\n grossUp = result.payrollGrossUpResponse?.grossUp ?? null\n\n if (grossUp) {\n onEvent(componentEvents.RUN_PAYROLL_GROSS_UP_CALCULATED, {\n grossUp,\n netPay,\n employeeUuid: grossUpEmployeeUuid,\n })\n }\n })\n\n return grossUp\n }\n\n const onGrossUpApply = async (grossAmount: string) => {\n if (!grossUpEmployeeUuid || !grossUpTargetCompensation) {\n throw new SDKInternalError(\n 'Unable to apply gross-up: missing employee or target compensation.',\n )\n }\n\n const employeeComp = employeeCompensations.find(ec => ec.employeeUuid === grossUpEmployeeUuid)\n if (!employeeComp) {\n throw new SDKInternalError('Unable to apply gross-up: employee compensation not found.')\n }\n\n const existingFixed = employeeComp.fixedCompensations ?? []\n const hasTargetCompensation = existingFixed.some(\n fc => fc.name?.toLowerCase() === grossUpTargetCompensation.toLowerCase(),\n )\n\n const updatedFixedCompensations = existingFixed.map(fc => ({\n name: fc.name,\n jobUuid: fc.jobUuid,\n amount:\n fc.name?.toLowerCase() === grossUpTargetCompensation.toLowerCase() ? grossAmount : '0',\n }))\n\n if (!hasTargetCompensation) {\n const primaryJobUuid =\n employeeComp.hourlyCompensations?.[0]?.jobUuid ?? existingFixed[0]?.jobUuid ?? ''\n updatedFixedCompensations.push({\n name: grossUpTargetCompensation,\n jobUuid: primaryJobUuid,\n amount: grossAmount,\n })\n }\n\n const updatedHourlyCompensations = (employeeComp.hourlyCompensations ?? []).map(hc => ({\n name: hc.name,\n jobUuid: hc.jobUuid,\n hours: '0',\n }))\n\n const updatedPaidTimeOff = (employeeComp.paidTimeOff ?? []).map(pto => ({\n name: pto.name,\n hours: '0',\n }))\n\n const transformedCompensation = transformEmployeeCompensation({\n ...employeeComp,\n fixedCompensations: updatedFixedCompensations,\n hourlyCompensations: updatedHourlyCompensations,\n paidTimeOff: updatedPaidTimeOff,\n })\n\n await baseSubmitHandler({}, async () => {\n const result = await updatePayroll({\n request: {\n companyId,\n payrollId,\n payrollUpdate: {\n employeeCompensations: [{ ...transformedCompensation, excluded: false }],\n },\n },\n })\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SAVED, {\n payrollPrepared: result.payrollPrepared,\n })\n await refetch()\n })\n\n setGrossUpEmployeeUuid(null)\n setIsGrossUpModalOpen(false)\n }\n\n const handleGrossUpApply = async (grossAmount: string) => {\n try {\n await onGrossUpApply(grossAmount)\n } catch {\n // Modal stays open; error is surfaced by baseSubmitHandler\n }\n }\n\n const { data: blockersData } = usePayrollsGetBlockersSuspense({\n companyUuid: companyId,\n })\n\n const payrollBlockerList = blockersData.payrollBlockers ?? []\n\n const blockersFromApi: ApiPayrollBlocker[] = payrollBlockerList.map(blocker => ({\n key: blocker.key,\n message: blocker.message,\n }))\n\n const [payrollBlockers, setPayrollBlockers] = useState(blockersFromApi)\n\n const onCalculatePayroll = async () => {\n setPayrollBlockers([])\n // Mark it right away so prepare can't run and cancel the calculation we just started.\n hasSeenCalculatingRef.current = true\n previousCalculatedAtRef.current = payrollData.payrollShow?.calculatedAt?.getTime() ?? null\n\n await baseSubmitHandler({}, async () => {\n const result = await payrollSubmitHandler(async () => {\n setIsCalculatingPayroll(true)\n try {\n const calcResult = await payrollsCalculate(gustoClient, {\n companyId,\n payrollId,\n })\n if (!calcResult.ok) {\n throw calcResult.error\n }\n setIsPolling(true)\n } finally {\n setIsCalculatingPayroll(false)\n }\n })\n\n if (!result.success && result.blockers.length > 0) {\n setPayrollBlockers(result.blockers)\n }\n })\n }\n\n const onEdit = (employee: Employee) => {\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_EDIT, {\n employeeId: employee.uuid,\n firstName: employee.firstName,\n lastName: employee.lastName,\n })\n }\n\n const transformEmployeeCompensation = (\n compensation: PayrollEmployeeCompensationsType,\n ): PayrollUpdateEmployeeCompensations => {\n const { paymentMethod } = compensation\n return {\n employeeUuid: compensation.employeeUuid,\n version: compensation.version,\n excluded: compensation.excluded,\n fixedCompensations: compensation.fixedCompensations,\n hourlyCompensations: compensation.hourlyCompensations,\n paidTimeOff: compensation.paidTimeOff,\n deductions: compensation.deductions,\n ...(paymentMethod && paymentMethod !== 'Historical' ? { paymentMethod } : {}),\n memo: compensation.memo || undefined,\n }\n }\n\n const onToggleExclude = async (employeeCompensation: PayrollEmployeeCompensationsType) => {\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SKIP, {\n employeeId: employeeCompensation.employeeUuid,\n })\n await baseSubmitHandler({}, async () => {\n const transformedCompensation = transformEmployeeCompensation(employeeCompensation)\n const result = await updatePayroll({\n request: {\n companyId,\n payrollId,\n payrollUpdate: {\n employeeCompensations: [\n { ...transformedCompensation, excluded: !transformedCompensation.excluded },\n ],\n },\n },\n })\n onEvent(componentEvents.RUN_PAYROLL_EMPLOYEE_SAVED, {\n payrollPrepared: result.payrollPrepared,\n })\n await refetch()\n })\n }\n\n const onViewBlockers = () => {\n onEvent(componentEvents.RUN_PAYROLL_BLOCKERS_VIEW_ALL)\n }\n\n useEffect(() => {\n if (isCalculatingStatus(payrollData.payrollShow?.processingRequest) && !isPolling) {\n previousCalculatedAtRef.current = payrollData.payrollShow?.calculatedAt?.getTime() ?? null\n setIsPolling(true)\n }\n const currentCalculatedAt = payrollData.payrollShow?.calculatedAt\n const isNewCalculation = currentCalculatedAt?.getTime() !== previousCalculatedAtRef.current\n if (\n isPolling &&\n isNewCalculation &&\n isCalculatedStatus(payrollData.payrollShow?.processingRequest, currentCalculatedAt)\n ) {\n onEvent(componentEvents.RUN_PAYROLL_CALCULATED, {\n payrollId,\n alert: {\n type: 'success',\n title: t('alerts.progressSaved'),\n alertKey: 'progressSaved',\n },\n payPeriod: payrollData.payrollShow?.payPeriod,\n })\n setPayrollBlockers([])\n setIsPolling(false)\n }\n if (\n isPolling &&\n payrollData.payrollShow?.processingRequest?.status ===\n PayrollProcessingRequestStatus.ProcessingFailed\n ) {\n onEvent(componentEvents.RUN_PAYROLL_PROCESSING_FAILED)\n setIsPolling(false)\n // Calculation failed, so let prepare run again on retry.\n hasSeenCalculatingRef.current = false\n }\n }, [\n payrollData.payrollShow?.processingRequest?.status,\n payrollData.payrollShow?.calculatedAt,\n isPolling,\n onEvent,\n t,\n payrollId,\n ])\n\n useEffect(() => {\n if (!isPolling) return\n\n const POLLING_TIMEOUT_MS = 3 * 60 * 1000\n const timeoutId = setTimeout(() => {\n onEvent(componentEvents.RUN_PAYROLL_PROCESSING_FAILED)\n setIsPolling(false)\n // Timed out waiting on the calculation, so let prepare run again.\n hasSeenCalculatingRef.current = false\n }, POLLING_TIMEOUT_MS)\n\n return () => {\n clearTimeout(timeoutId)\n }\n }, [isPolling, onEvent])\n\n const payrollAlert = (() => {\n const statusMeta = payrollData.payrollShow?.payrollStatusMeta\n\n const isLatePayroll =\n statusMeta?.payrollLate &&\n statusMeta.initialCheckDate &&\n statusMeta.expectedDebitTime &&\n statusMeta.expectedCheckDate\n\n if (isLatePayroll) {\n return {\n label: t('alerts.payrollLate', {\n initialCheckDate: dateFormatter.formatShortWithWeekday(statusMeta.initialCheckDate),\n }),\n content: t('alerts.payrollLateText', {\n ...dateFormatter.formatWithTime(statusMeta.expectedDebitTime),\n newCheckDate: dateFormatter.formatShortWithWeekday(statusMeta.expectedCheckDate),\n }),\n variant: 'warning' as const,\n }\n }\n\n const { payrollShow } = payrollData\n\n if (payrollShow?.checkDate && payrollShow.payrollDeadline) {\n return {\n label: t('alerts.directDepositDeadline', {\n payDate: dateFormatter.formatShortWithWeekday(payrollShow.checkDate),\n ...dateFormatter.formatWithTime(payrollShow.payrollDeadline),\n }),\n content: t('alerts.directDepositDeadlineText'),\n variant: 'info' as const,\n }\n }\n\n return undefined\n })()\n\n if (isAlreadyProcessed) {\n const onAlreadyProcessedOverviewEvent = (type: EventType, data?: unknown) => {\n if (type === componentEvents.RUN_PAYROLL_CANCELLED) {\n // Cancelling un-processes the payroll, making it editable again — re-run prepare so\n // this component drops back into the configuration table for the same payrollId.\n void refetch()\n }\n onEvent(type, data)\n }\n\n return (\n <PayrollOverview\n companyId={companyId}\n payrollId={payrollId}\n onEvent={onAlreadyProcessedOverviewEvent}\n withReimbursements={withReimbursements}\n alerts={[alreadyProcessedAlert]}\n />\n )\n }\n\n return (\n <>\n <PayrollConfigurationPresentation\n onCalculatePayroll={onCalculatePayroll}\n isCalculateDisabled={blockersFromApi.length > 0}\n onEdit={onEdit}\n onToggleExclude={onToggleExclude}\n onViewBlockers={onViewBlockers}\n employeeCompensations={employeeCompensations}\n employeeDetails={employeeDetails}\n payPeriod={payPeriod}\n paySchedule={paySchedule}\n payrollCategory={payrollCategory}\n alerts={alerts}\n payrollAlert={payrollAlert}\n isPending={isCalculatingActive || isLoading || isUpdatingPayroll}\n isCalculating={isCalculatingActive}\n payrollBlockers={payrollBlockers}\n pagination={pagination}\n withReimbursements={withReimbursements}\n grossUpEnabled={grossUpEnabled}\n onGrossUpSelect={onGrossUpSelect}\n />\n {grossUpEnabled && (\n <GrossUpModal\n isOpen={isGrossUpModalOpen}\n onCalculateGrossUp={onCalculateGrossUp}\n onApply={handleGrossUpApply}\n onCancel={() => {\n setIsGrossUpModalOpen(false)\n }}\n />\n )}\n </>\n )\n}\n"],"names":["isCalculatingStatus","processingRequest","PayrollProcessingRequestStatus","isCalculatedStatus","calculatedAt","PayrollConfiguration","props","jsx","BaseComponent","Root","onEvent","companyId","payrollId","dictionary","alerts","withReimbursements","useComponentDictionary","useI18n","t","useTranslation","baseSubmitHandler","useBase","dateFormatter","useDateFormatter","isPolling","setIsPolling","useState","isCalculatingPayroll","setIsCalculatingPayroll","previousCalculatedAtRef","useRef","hasSeenCalculatingRef","gustoClient","useGustoEmbeddedContext","payrollData","usePayrollsGetSuspense","excludedEmployeeUuids","useMemo","comp","isCalculatingActive","employeeDetails","employeeCompensations","paySchedule","payPeriod","payrollCategory","pagination","isLoading","isAlreadyProcessed","refetch","usePayrollConfigurationData","alreadyProcessedAlert","hasFiredAlreadyProcessedRef","useEffect","componentEvents","updatePayroll","isUpdatingPayroll","usePayrollsUpdateMutation","calculateGrossUpMutation","usePayrollsCalculateGrossUpMutation","grossUpEmployeeUuid","setGrossUpEmployeeUuid","isGrossUpModalOpen","setIsGrossUpModalOpen","grossUpEnabled","isGrossUpEligible","grossUpTargetCompensation","getGrossUpTargetCompensationName","onGrossUpSelect","employeeUuid","onCalculateGrossUp","netPay","grossUp","onGrossUpApply","grossAmount","SDKInternalError","employeeComp","ec","existingFixed","hasTargetCompensation","fc","updatedFixedCompensations","primaryJobUuid","updatedHourlyCompensations","hc","updatedPaidTimeOff","pto","transformedCompensation","transformEmployeeCompensation","result","handleGrossUpApply","blockersData","usePayrollsGetBlockersSuspense","blockersFromApi","blocker","payrollBlockers","setPayrollBlockers","onCalculatePayroll","payrollSubmitHandler","calcResult","payrollsCalculate","onEdit","employee","compensation","paymentMethod","onToggleExclude","employeeCompensation","onViewBlockers","currentCalculatedAt","isNewCalculation","POLLING_TIMEOUT_MS","timeoutId","payrollAlert","statusMeta","payrollShow","PayrollOverview","type","data","jsxs","Fragment","PayrollConfigurationPresentation","GrossUpModal"],"mappings":"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"}
|
|
@@ -7,7 +7,8 @@ import { PaginationControlProps } from '../../Common/PaginationControl/Paginatio
|
|
|
7
7
|
interface UsePayrollConfigurationDataParams {
|
|
8
8
|
companyId: string;
|
|
9
9
|
payrollId: string;
|
|
10
|
-
|
|
10
|
+
/** When true, don't call prepare and cancel any prepare already running. */
|
|
11
|
+
disablePrepare?: boolean;
|
|
11
12
|
excludedEmployeeUuids?: string[];
|
|
12
13
|
}
|
|
13
14
|
interface UsePayrollConfigurationDataReturn {
|
|
@@ -24,5 +25,5 @@ interface UsePayrollConfigurationDataReturn {
|
|
|
24
25
|
/** @internal */
|
|
25
26
|
export declare const PREPARE_QUERY_KEY = "payroll-prepare";
|
|
26
27
|
/** @internal */
|
|
27
|
-
export declare function usePayrollConfigurationData({ companyId, payrollId,
|
|
28
|
+
export declare function usePayrollConfigurationData({ companyId, payrollId, disablePrepare, excludedEmployeeUuids, }: UsePayrollConfigurationDataParams): UsePayrollConfigurationDataReturn;
|
|
28
29
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState as q, useRef as v, useMemo as y, useEffect as
|
|
1
|
+
import { useState as q, useRef as v, useMemo as y, useEffect as P, useCallback as L } from "react";
|
|
2
2
|
import { useEmployeesList as ee } from "@gusto/embedded-api/react-query/employeesList";
|
|
3
3
|
import { useQueryClient as te, keepPreviousData as F, useQuery as K } from "@tanstack/react-query";
|
|
4
4
|
import { usePaySchedulesGet as se } from "@gusto/embedded-api/react-query/paySchedulesGet";
|
|
@@ -8,36 +8,36 @@ import { employeesGet as ae } from "@gusto/embedded-api/funcs/employeesGet";
|
|
|
8
8
|
import { UnprocessableEntityError as ne } from "@gusto/embedded-api/models/errors/unprocessableentityerror";
|
|
9
9
|
import { derivePayrollCategory as ie } from "../payrollTypes.js";
|
|
10
10
|
import { usePagination as le } from "../../../hooks/usePagination/usePagination.js";
|
|
11
|
-
const f = "payroll-prepare", _ = 300 * 1e3, ue = 3,
|
|
11
|
+
const f = "payroll-prepare", _ = 300 * 1e3, ue = 3, A = (n) => n instanceof ne ? n.errors.some((s) => s.category === "invalid_operation") : !1;
|
|
12
12
|
function De({
|
|
13
13
|
companyId: n,
|
|
14
14
|
payrollId: s,
|
|
15
|
-
|
|
15
|
+
disablePrepare: m = !1,
|
|
16
16
|
excludedEmployeeUuids: S = []
|
|
17
17
|
}) {
|
|
18
|
-
const D = oe(), i = te(), { currentPage: c, itemsPerPage:
|
|
18
|
+
const D = oe(), i = te(), { currentPage: c, itemsPerPage: Q, getPaginationProps: T } = le({
|
|
19
19
|
defaultItemsPerPage: 25
|
|
20
|
-
}), [
|
|
20
|
+
}), [k, x] = q([]), [M, h] = q(!1), g = v(!1), { data: l, isFetching: w } = ee(
|
|
21
21
|
{
|
|
22
22
|
companyId: n,
|
|
23
23
|
payrollUuid: s,
|
|
24
|
-
per:
|
|
24
|
+
per: Q,
|
|
25
25
|
page: c,
|
|
26
26
|
sortBy: "name"
|
|
27
27
|
},
|
|
28
28
|
{ placeholderData: F }
|
|
29
|
-
),
|
|
30
|
-
|
|
29
|
+
), C = v(l);
|
|
30
|
+
C.current = l;
|
|
31
31
|
const p = y(() => l?.showEmployees?.map((e) => e.uuid) || [], [l?.showEmployees]), u = y(() => {
|
|
32
32
|
const e = new Set(p);
|
|
33
33
|
return S.filter((t) => !e.has(t));
|
|
34
|
-
}, [S, p]),
|
|
34
|
+
}, [S, p]), d = y(() => c === 1 ? [...p, ...u] : p, [p, u, c]), b = y(() => d.join(","), [d]), {
|
|
35
35
|
data: r,
|
|
36
36
|
error: B,
|
|
37
37
|
isLoading: G,
|
|
38
38
|
isFetching: j
|
|
39
39
|
} = K({
|
|
40
|
-
queryKey: [f, s,
|
|
40
|
+
queryKey: [f, s, b],
|
|
41
41
|
queryFn: async ({ signal: e }) => {
|
|
42
42
|
const t = await re(
|
|
43
43
|
D,
|
|
@@ -46,7 +46,7 @@ function De({
|
|
|
46
46
|
payrollId: s,
|
|
47
47
|
sortBy: "last_name",
|
|
48
48
|
requestBody: {
|
|
49
|
-
employeeUuids:
|
|
49
|
+
employeeUuids: d
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
{ signal: e }
|
|
@@ -55,23 +55,23 @@ function De({
|
|
|
55
55
|
throw t.error;
|
|
56
56
|
return t.value.payrollPrepared;
|
|
57
57
|
},
|
|
58
|
-
enabled:
|
|
58
|
+
enabled: d.length > 0 && !m,
|
|
59
59
|
staleTime: _,
|
|
60
60
|
placeholderData: F,
|
|
61
61
|
// An "already processed" prepare failure is terminal — retrying it wastes time. Other
|
|
62
62
|
// errors (network blips, etc.) still get the standard retry treatment.
|
|
63
|
-
retry: (e, t) => !
|
|
64
|
-
}), I =
|
|
65
|
-
|
|
63
|
+
retry: (e, t) => !A(t) && e < ue
|
|
64
|
+
}), I = A(B);
|
|
65
|
+
P(() => () => {
|
|
66
66
|
i.cancelQueries({
|
|
67
67
|
queryKey: [f, s]
|
|
68
68
|
});
|
|
69
|
-
}, [i, s]),
|
|
70
|
-
|
|
69
|
+
}, [i, s]), P(() => {
|
|
70
|
+
m && i.cancelQueries({
|
|
71
71
|
queryKey: [f, s]
|
|
72
72
|
});
|
|
73
|
-
}, [
|
|
74
|
-
const Y = y(() => u.join(","), [u]), { data:
|
|
73
|
+
}, [m, i, s]);
|
|
74
|
+
const Y = y(() => u.join(","), [u]), { data: E } = K({
|
|
75
75
|
queryKey: ["excluded-employee-details", Y],
|
|
76
76
|
queryFn: async () => {
|
|
77
77
|
const e = await Promise.all(
|
|
@@ -81,10 +81,10 @@ function De({
|
|
|
81
81
|
throw t.error;
|
|
82
82
|
return e.filter((o) => o.ok).map((o) => o.value.employee).filter((o) => o != null);
|
|
83
83
|
},
|
|
84
|
-
enabled: u.length > 0 && !
|
|
84
|
+
enabled: u.length > 0 && !m,
|
|
85
85
|
staleTime: _
|
|
86
|
-
}),
|
|
87
|
-
const e =
|
|
86
|
+
}), U = L(() => {
|
|
87
|
+
const e = C.current;
|
|
88
88
|
if (!e?.showEmployees || !r?.employeeCompensations) {
|
|
89
89
|
h(!1);
|
|
90
90
|
return;
|
|
@@ -92,18 +92,18 @@ function De({
|
|
|
92
92
|
const t = e.showEmployees.map((a) => a.uuid), o = new Set(r.employeeCompensations.map((a) => a.employeeUuid));
|
|
93
93
|
if (t.length > 0 && t.every((a) => o.has(a))) {
|
|
94
94
|
const a = [...e.showEmployees];
|
|
95
|
-
if (c === 1 &&
|
|
95
|
+
if (c === 1 && E?.length) {
|
|
96
96
|
const $ = new Set(t);
|
|
97
|
-
for (const R of
|
|
97
|
+
for (const R of E)
|
|
98
98
|
$.has(R.uuid) || a.push(R);
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
x(a), h(!0), g.current = !0;
|
|
101
101
|
} else
|
|
102
102
|
h(!1);
|
|
103
|
-
}, [r?.employeeCompensations,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}, [
|
|
103
|
+
}, [r?.employeeCompensations, E, c]);
|
|
104
|
+
P(() => {
|
|
105
|
+
U();
|
|
106
|
+
}, [U]);
|
|
107
107
|
const { data: H, isLoading: N } = se(
|
|
108
108
|
{
|
|
109
109
|
companyId: n,
|
|
@@ -116,10 +116,10 @@ function De({
|
|
|
116
116
|
await i.invalidateQueries({
|
|
117
117
|
queryKey: [f, s]
|
|
118
118
|
});
|
|
119
|
-
}, [i, s]), X = G && !
|
|
119
|
+
}, [i, s]), X = G && !g.current, z = j && g.current, J = w || z || !M, O = X || N || !l && w, W = l?.httpMeta.response.headers ?? new Headers(), Z = T(W, J);
|
|
120
120
|
return {
|
|
121
121
|
employeeCompensations: r?.employeeCompensations ?? [],
|
|
122
|
-
employeeDetails:
|
|
122
|
+
employeeDetails: k,
|
|
123
123
|
payPeriod: r?.payPeriod,
|
|
124
124
|
paySchedule: H?.payScheduleShow,
|
|
125
125
|
payrollCategory: ie(r ?? {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePayrollConfigurationData.js","sources":["../../../../src/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useEmployeesList } from '@gusto/embedded-api/react-query/employeesList'\nimport { keepPreviousData, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { usePaySchedulesGet } from '@gusto/embedded-api/react-query/paySchedulesGet'\nimport { useGustoEmbeddedContext } from '@gusto/embedded-api/react-query/_context'\nimport { payrollsPrepare } from '@gusto/embedded-api/funcs/payrollsPrepare'\nimport { employeesGet } from '@gusto/embedded-api/funcs/employeesGet'\nimport { UnprocessableEntityError } from '@gusto/embedded-api/models/errors/unprocessableentityerror'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { Employee } from '@gusto/embedded-api/models/components/employee'\nimport type { PayrollPayPeriodType } from '@gusto/embedded-api/models/components/payrollpayperiodtype'\nimport type { PayScheduleShow } from '@gusto/embedded-api/models/components/payscheduleshow'\nimport type { PayrollCategory } from '../payrollTypes'\nimport { derivePayrollCategory } from '../payrollTypes'\nimport type { PaginationControlProps } from '@/components/Common/PaginationControl/PaginationControlTypes'\nimport { usePagination } from '@/hooks/usePagination/usePagination'\n\ninterface UsePayrollConfigurationDataParams {\n companyId: string\n payrollId: string\n isCalculating?: boolean\n excludedEmployeeUuids?: string[]\n}\n\ninterface UsePayrollConfigurationDataReturn {\n employeeCompensations: PayrollEmployeeCompensationsType[]\n employeeDetails: Employee[]\n payPeriod: PayrollPayPeriodType | undefined\n paySchedule: PayScheduleShow | undefined\n payrollCategory: PayrollCategory\n pagination: PaginationControlProps\n isLoading: boolean\n isAlreadyProcessed: boolean\n refetch: () => Promise<void>\n}\n\n/** @internal */\nexport const PREPARE_QUERY_KEY = 'payroll-prepare'\nconst FIVE_MINUTES = 5 * 60 * 1000\nconst PREPARE_MAX_ATTEMPTS = 3\n\nconst isAlreadyProcessedError = (error: unknown): boolean => {\n if (!(error instanceof UnprocessableEntityError)) return false\n return error.errors.some(e => e.category === 'invalid_operation')\n}\n\n/** @internal */\nexport function usePayrollConfigurationData({\n companyId,\n payrollId,\n isCalculating = false,\n excludedEmployeeUuids = [],\n}: UsePayrollConfigurationDataParams): UsePayrollConfigurationDataReturn {\n const gustoClient = useGustoEmbeddedContext()\n const queryClient = useQueryClient()\n\n const { currentPage, itemsPerPage, getPaginationProps } = usePagination({\n defaultItemsPerPage: 25,\n })\n const [displayedEmployees, setDisplayedEmployees] = useState<Employee[]>([])\n const [isDataInSync, setIsDataInSync] = useState(false)\n const hasInitialDataRef = useRef(false)\n\n const { data: employeeData, isFetching: isFetchingEmployeeData } = useEmployeesList(\n {\n companyId,\n payrollUuid: payrollId,\n per: itemsPerPage,\n page: currentPage,\n sortBy: 'name',\n },\n { placeholderData: keepPreviousData },\n )\n\n const employeeDataRef = useRef(employeeData)\n employeeDataRef.current = employeeData\n\n const listedEmployeeUuids = useMemo(() => {\n return employeeData?.showEmployees?.map(e => e.uuid) || []\n }, [employeeData?.showEmployees])\n\n const missingExcludedUuids = useMemo(() => {\n const listedSet = new Set(listedEmployeeUuids)\n return excludedEmployeeUuids.filter(uuid => !listedSet.has(uuid))\n }, [excludedEmployeeUuids, listedEmployeeUuids])\n\n const employeeUuids = useMemo(() => {\n if (currentPage === 1) {\n return [...listedEmployeeUuids, ...missingExcludedUuids]\n }\n return listedEmployeeUuids\n }, [listedEmployeeUuids, missingExcludedUuids, currentPage])\n\n const employeeUuidsKey = useMemo(() => employeeUuids.join(','), [employeeUuids])\n\n const {\n data: prepareData,\n error: prepareError,\n isLoading: isPrepareLoading,\n isFetching: isPrepareFetching,\n } = useQuery({\n queryKey: [PREPARE_QUERY_KEY, payrollId, employeeUuidsKey],\n queryFn: async ({ signal }) => {\n const result = await payrollsPrepare(\n gustoClient,\n {\n companyId,\n payrollId,\n sortBy: 'last_name',\n requestBody: {\n employeeUuids,\n },\n },\n { signal },\n )\n\n if (!result.ok) {\n throw result.error\n }\n\n return result.value.payrollPrepared\n },\n enabled: employeeUuids.length > 0 && !isCalculating,\n staleTime: FIVE_MINUTES,\n placeholderData: keepPreviousData,\n // An \"already processed\" prepare failure is terminal — retrying it wastes time. Other\n // errors (network blips, etc.) still get the standard retry treatment.\n retry: (failureCount, error) =>\n !isAlreadyProcessedError(error) && failureCount < PREPARE_MAX_ATTEMPTS,\n })\n\n const isAlreadyProcessed = isAlreadyProcessedError(prepareError)\n\n useEffect(() => {\n return () => {\n void queryClient.cancelQueries({\n queryKey: [PREPARE_QUERY_KEY, payrollId],\n })\n }\n }, [queryClient, payrollId])\n\n useEffect(() => {\n if (isCalculating) {\n void queryClient.cancelQueries({\n queryKey: [PREPARE_QUERY_KEY, payrollId],\n })\n }\n }, [isCalculating, queryClient, payrollId])\n\n const excludedUuidsKey = useMemo(() => missingExcludedUuids.join(','), [missingExcludedUuids])\n\n const { data: excludedEmployeeDetails } = useQuery({\n queryKey: ['excluded-employee-details', excludedUuidsKey],\n queryFn: async () => {\n const results = await Promise.all(\n missingExcludedUuids.map(uuid => employeesGet(gustoClient, { employeeId: uuid })),\n )\n const failedResult = results.find(result => !result.ok)\n if (failedResult) {\n throw failedResult.error\n }\n\n return results\n .filter(result => result.ok)\n .map(result => result.value.employee)\n .filter((e): e is Employee => e != null)\n },\n enabled: missingExcludedUuids.length > 0 && !isCalculating,\n staleTime: FIVE_MINUTES,\n })\n\n const syncData = useCallback(() => {\n const currentEmployeeData = employeeDataRef.current\n if (!currentEmployeeData?.showEmployees || !prepareData?.employeeCompensations) {\n setIsDataInSync(false)\n return\n }\n\n const currentUuids = currentEmployeeData.showEmployees.map(e => e.uuid)\n const preparedUuids = new Set(prepareData.employeeCompensations.map(c => c.employeeUuid))\n const allListedInSync =\n currentUuids.length > 0 && currentUuids.every(uuid => preparedUuids.has(uuid))\n\n if (allListedInSync) {\n const mergedEmployees = [...currentEmployeeData.showEmployees]\n if (currentPage === 1 && excludedEmployeeDetails?.length) {\n const listedSet = new Set(currentUuids)\n for (const employee of excludedEmployeeDetails) {\n if (!listedSet.has(employee.uuid)) {\n mergedEmployees.push(employee)\n }\n }\n }\n setDisplayedEmployees(mergedEmployees)\n setIsDataInSync(true)\n hasInitialDataRef.current = true\n } else {\n setIsDataInSync(false)\n }\n }, [prepareData?.employeeCompensations, excludedEmployeeDetails, currentPage])\n\n useEffect(() => {\n syncData()\n }, [syncData])\n\n const { data: payScheduleData, isLoading: isPayScheduleLoading } = usePaySchedulesGet(\n {\n companyId,\n payScheduleId: prepareData?.payPeriod?.payScheduleUuid || '',\n },\n {\n enabled: !!prepareData?.payPeriod?.payScheduleUuid,\n },\n )\n\n const handleRefetch = useCallback(async () => {\n await queryClient.invalidateQueries({\n queryKey: [PREPARE_QUERY_KEY, payrollId],\n })\n }, [queryClient, payrollId])\n\n const isInitialLoading = isPrepareLoading && !hasInitialDataRef.current\n const isPaginating = isPrepareFetching && hasInitialDataRef.current\n const isPaginationFetching = isFetchingEmployeeData || isPaginating || !isDataInSync\n const isLoading =\n isInitialLoading || isPayScheduleLoading || (!employeeData && isFetchingEmployeeData)\n\n const headers = employeeData?.httpMeta.response.headers ?? new Headers()\n const pagination: PaginationControlProps = getPaginationProps(headers, isPaginationFetching)\n\n return {\n employeeCompensations: prepareData?.employeeCompensations ?? [],\n employeeDetails: displayedEmployees,\n payPeriod: prepareData?.payPeriod,\n paySchedule: payScheduleData?.payScheduleShow,\n payrollCategory: derivePayrollCategory(prepareData ?? {}),\n pagination,\n isLoading,\n isAlreadyProcessed,\n refetch: handleRefetch,\n }\n}\n"],"names":["PREPARE_QUERY_KEY","FIVE_MINUTES","PREPARE_MAX_ATTEMPTS","isAlreadyProcessedError","error","UnprocessableEntityError","e","usePayrollConfigurationData","companyId","payrollId","isCalculating","excludedEmployeeUuids","gustoClient","useGustoEmbeddedContext","queryClient","useQueryClient","currentPage","itemsPerPage","getPaginationProps","usePagination","displayedEmployees","setDisplayedEmployees","useState","isDataInSync","setIsDataInSync","hasInitialDataRef","useRef","employeeData","isFetchingEmployeeData","useEmployeesList","keepPreviousData","employeeDataRef","listedEmployeeUuids","useMemo","missingExcludedUuids","listedSet","uuid","employeeUuids","employeeUuidsKey","prepareData","prepareError","isPrepareLoading","isPrepareFetching","useQuery","signal","result","payrollsPrepare","failureCount","isAlreadyProcessed","useEffect","excludedUuidsKey","excludedEmployeeDetails","results","employeesGet","failedResult","syncData","useCallback","currentEmployeeData","currentUuids","preparedUuids","c","mergedEmployees","employee","payScheduleData","isPayScheduleLoading","usePaySchedulesGet","handleRefetch","isInitialLoading","isPaginating","isPaginationFetching","isLoading","headers","pagination","derivePayrollCategory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePayrollConfigurationData.js","sources":["../../../../src/components/Payroll/PayrollConfiguration/usePayrollConfigurationData.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useEmployeesList } from '@gusto/embedded-api/react-query/employeesList'\nimport { keepPreviousData, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { usePaySchedulesGet } from '@gusto/embedded-api/react-query/paySchedulesGet'\nimport { useGustoEmbeddedContext } from '@gusto/embedded-api/react-query/_context'\nimport { payrollsPrepare } from '@gusto/embedded-api/funcs/payrollsPrepare'\nimport { employeesGet } from '@gusto/embedded-api/funcs/employeesGet'\nimport { UnprocessableEntityError } from '@gusto/embedded-api/models/errors/unprocessableentityerror'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { Employee } from '@gusto/embedded-api/models/components/employee'\nimport type { PayrollPayPeriodType } from '@gusto/embedded-api/models/components/payrollpayperiodtype'\nimport type { PayScheduleShow } from '@gusto/embedded-api/models/components/payscheduleshow'\nimport type { PayrollCategory } from '../payrollTypes'\nimport { derivePayrollCategory } from '../payrollTypes'\nimport type { PaginationControlProps } from '@/components/Common/PaginationControl/PaginationControlTypes'\nimport { usePagination } from '@/hooks/usePagination/usePagination'\n\ninterface UsePayrollConfigurationDataParams {\n companyId: string\n payrollId: string\n /** When true, don't call prepare and cancel any prepare already running. */\n disablePrepare?: boolean\n excludedEmployeeUuids?: string[]\n}\n\ninterface UsePayrollConfigurationDataReturn {\n employeeCompensations: PayrollEmployeeCompensationsType[]\n employeeDetails: Employee[]\n payPeriod: PayrollPayPeriodType | undefined\n paySchedule: PayScheduleShow | undefined\n payrollCategory: PayrollCategory\n pagination: PaginationControlProps\n isLoading: boolean\n isAlreadyProcessed: boolean\n refetch: () => Promise<void>\n}\n\n/** @internal */\nexport const PREPARE_QUERY_KEY = 'payroll-prepare'\nconst FIVE_MINUTES = 5 * 60 * 1000\nconst PREPARE_MAX_ATTEMPTS = 3\n\nconst isAlreadyProcessedError = (error: unknown): boolean => {\n if (!(error instanceof UnprocessableEntityError)) return false\n return error.errors.some(e => e.category === 'invalid_operation')\n}\n\n/** @internal */\nexport function usePayrollConfigurationData({\n companyId,\n payrollId,\n disablePrepare = false,\n excludedEmployeeUuids = [],\n}: UsePayrollConfigurationDataParams): UsePayrollConfigurationDataReturn {\n const gustoClient = useGustoEmbeddedContext()\n const queryClient = useQueryClient()\n\n const { currentPage, itemsPerPage, getPaginationProps } = usePagination({\n defaultItemsPerPage: 25,\n })\n const [displayedEmployees, setDisplayedEmployees] = useState<Employee[]>([])\n const [isDataInSync, setIsDataInSync] = useState(false)\n const hasInitialDataRef = useRef(false)\n\n const { data: employeeData, isFetching: isFetchingEmployeeData } = useEmployeesList(\n {\n companyId,\n payrollUuid: payrollId,\n per: itemsPerPage,\n page: currentPage,\n sortBy: 'name',\n },\n { placeholderData: keepPreviousData },\n )\n\n const employeeDataRef = useRef(employeeData)\n employeeDataRef.current = employeeData\n\n const listedEmployeeUuids = useMemo(() => {\n return employeeData?.showEmployees?.map(e => e.uuid) || []\n }, [employeeData?.showEmployees])\n\n const missingExcludedUuids = useMemo(() => {\n const listedSet = new Set(listedEmployeeUuids)\n return excludedEmployeeUuids.filter(uuid => !listedSet.has(uuid))\n }, [excludedEmployeeUuids, listedEmployeeUuids])\n\n const employeeUuids = useMemo(() => {\n if (currentPage === 1) {\n return [...listedEmployeeUuids, ...missingExcludedUuids]\n }\n return listedEmployeeUuids\n }, [listedEmployeeUuids, missingExcludedUuids, currentPage])\n\n const employeeUuidsKey = useMemo(() => employeeUuids.join(','), [employeeUuids])\n\n const {\n data: prepareData,\n error: prepareError,\n isLoading: isPrepareLoading,\n isFetching: isPrepareFetching,\n } = useQuery({\n queryKey: [PREPARE_QUERY_KEY, payrollId, employeeUuidsKey],\n queryFn: async ({ signal }) => {\n const result = await payrollsPrepare(\n gustoClient,\n {\n companyId,\n payrollId,\n sortBy: 'last_name',\n requestBody: {\n employeeUuids,\n },\n },\n { signal },\n )\n\n if (!result.ok) {\n throw result.error\n }\n\n return result.value.payrollPrepared\n },\n enabled: employeeUuids.length > 0 && !disablePrepare,\n staleTime: FIVE_MINUTES,\n placeholderData: keepPreviousData,\n // An \"already processed\" prepare failure is terminal — retrying it wastes time. Other\n // errors (network blips, etc.) still get the standard retry treatment.\n retry: (failureCount, error) =>\n !isAlreadyProcessedError(error) && failureCount < PREPARE_MAX_ATTEMPTS,\n })\n\n const isAlreadyProcessed = isAlreadyProcessedError(prepareError)\n\n useEffect(() => {\n return () => {\n void queryClient.cancelQueries({\n queryKey: [PREPARE_QUERY_KEY, payrollId],\n })\n }\n }, [queryClient, payrollId])\n\n useEffect(() => {\n if (disablePrepare) {\n void queryClient.cancelQueries({\n queryKey: [PREPARE_QUERY_KEY, payrollId],\n })\n }\n }, [disablePrepare, queryClient, payrollId])\n\n const excludedUuidsKey = useMemo(() => missingExcludedUuids.join(','), [missingExcludedUuids])\n\n const { data: excludedEmployeeDetails } = useQuery({\n queryKey: ['excluded-employee-details', excludedUuidsKey],\n queryFn: async () => {\n const results = await Promise.all(\n missingExcludedUuids.map(uuid => employeesGet(gustoClient, { employeeId: uuid })),\n )\n const failedResult = results.find(result => !result.ok)\n if (failedResult) {\n throw failedResult.error\n }\n\n return results\n .filter(result => result.ok)\n .map(result => result.value.employee)\n .filter((e): e is Employee => e != null)\n },\n enabled: missingExcludedUuids.length > 0 && !disablePrepare,\n staleTime: FIVE_MINUTES,\n })\n\n const syncData = useCallback(() => {\n const currentEmployeeData = employeeDataRef.current\n if (!currentEmployeeData?.showEmployees || !prepareData?.employeeCompensations) {\n setIsDataInSync(false)\n return\n }\n\n const currentUuids = currentEmployeeData.showEmployees.map(e => e.uuid)\n const preparedUuids = new Set(prepareData.employeeCompensations.map(c => c.employeeUuid))\n const allListedInSync =\n currentUuids.length > 0 && currentUuids.every(uuid => preparedUuids.has(uuid))\n\n if (allListedInSync) {\n const mergedEmployees = [...currentEmployeeData.showEmployees]\n if (currentPage === 1 && excludedEmployeeDetails?.length) {\n const listedSet = new Set(currentUuids)\n for (const employee of excludedEmployeeDetails) {\n if (!listedSet.has(employee.uuid)) {\n mergedEmployees.push(employee)\n }\n }\n }\n setDisplayedEmployees(mergedEmployees)\n setIsDataInSync(true)\n hasInitialDataRef.current = true\n } else {\n setIsDataInSync(false)\n }\n }, [prepareData?.employeeCompensations, excludedEmployeeDetails, currentPage])\n\n useEffect(() => {\n syncData()\n }, [syncData])\n\n const { data: payScheduleData, isLoading: isPayScheduleLoading } = usePaySchedulesGet(\n {\n companyId,\n payScheduleId: prepareData?.payPeriod?.payScheduleUuid || '',\n },\n {\n enabled: !!prepareData?.payPeriod?.payScheduleUuid,\n },\n )\n\n const handleRefetch = useCallback(async () => {\n await queryClient.invalidateQueries({\n queryKey: [PREPARE_QUERY_KEY, payrollId],\n })\n }, [queryClient, payrollId])\n\n const isInitialLoading = isPrepareLoading && !hasInitialDataRef.current\n const isPaginating = isPrepareFetching && hasInitialDataRef.current\n const isPaginationFetching = isFetchingEmployeeData || isPaginating || !isDataInSync\n const isLoading =\n isInitialLoading || isPayScheduleLoading || (!employeeData && isFetchingEmployeeData)\n\n const headers = employeeData?.httpMeta.response.headers ?? new Headers()\n const pagination: PaginationControlProps = getPaginationProps(headers, isPaginationFetching)\n\n return {\n employeeCompensations: prepareData?.employeeCompensations ?? [],\n employeeDetails: displayedEmployees,\n payPeriod: prepareData?.payPeriod,\n paySchedule: payScheduleData?.payScheduleShow,\n payrollCategory: derivePayrollCategory(prepareData ?? {}),\n pagination,\n isLoading,\n isAlreadyProcessed,\n refetch: handleRefetch,\n }\n}\n"],"names":["PREPARE_QUERY_KEY","FIVE_MINUTES","PREPARE_MAX_ATTEMPTS","isAlreadyProcessedError","error","UnprocessableEntityError","e","usePayrollConfigurationData","companyId","payrollId","disablePrepare","excludedEmployeeUuids","gustoClient","useGustoEmbeddedContext","queryClient","useQueryClient","currentPage","itemsPerPage","getPaginationProps","usePagination","displayedEmployees","setDisplayedEmployees","useState","isDataInSync","setIsDataInSync","hasInitialDataRef","useRef","employeeData","isFetchingEmployeeData","useEmployeesList","keepPreviousData","employeeDataRef","listedEmployeeUuids","useMemo","missingExcludedUuids","listedSet","uuid","employeeUuids","employeeUuidsKey","prepareData","prepareError","isPrepareLoading","isPrepareFetching","useQuery","signal","result","payrollsPrepare","failureCount","isAlreadyProcessed","useEffect","excludedUuidsKey","excludedEmployeeDetails","results","employeesGet","failedResult","syncData","useCallback","currentEmployeeData","currentUuids","preparedUuids","c","mergedEmployees","employee","payScheduleData","isPayScheduleLoading","usePaySchedulesGet","handleRefetch","isInitialLoading","isPaginating","isPaginationFetching","isLoading","headers","pagination","derivePayrollCategory"],"mappings":"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"}
|