@gusto/embedded-react-sdk 0.55.7 → 0.55.8

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.
Files changed (336) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/components/Common/FadeIn/FadeIn.module.scss.js +4 -4
  3. package/dist/components/Common/FieldCaption/FieldCaption.js +22 -18
  4. package/dist/components/Common/FieldCaption/FieldCaption.js.map +1 -1
  5. package/dist/components/Common/Flex/Flex.js +17 -15
  6. package/dist/components/Common/Flex/Flex.js.map +1 -1
  7. package/dist/components/Common/UI/Breadcrumbs/Breadcrumbs.js +1 -1
  8. package/dist/components/Common/UI/FileInput/FileInput.js +1 -1
  9. package/dist/components/Common/UI/Heading/Heading.module.scss.js +7 -7
  10. package/dist/components/Common/UI/ProgressBar/ProgressBar.js +4 -4
  11. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js +5 -4
  12. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js.map +1 -1
  13. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js +5 -4
  14. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js.map +1 -1
  15. package/dist/components/Company/AssignSignatory/useAssignSignatory.js +7 -6
  16. package/dist/components/Company/AssignSignatory/useAssignSignatory.js.map +1 -1
  17. package/dist/components/Company/BankAccount/BankAccountForm/context.js +5 -4
  18. package/dist/components/Company/BankAccount/BankAccountForm/context.js.map +1 -1
  19. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js +5 -4
  20. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  21. package/dist/components/Company/DocumentSigner/SignatureForm/SignatureForm.js +27 -27
  22. package/dist/components/Company/DocumentSigner/SignatureForm/SignatureForm.js.map +1 -1
  23. package/dist/components/Company/FederalTaxes/useFederalTaxes.js +10 -9
  24. package/dist/components/Company/FederalTaxes/useFederalTaxes.js.map +1 -1
  25. package/dist/components/Company/Industry/Context.js +8 -7
  26. package/dist/components/Company/Industry/Context.js.map +1 -1
  27. package/dist/components/Company/Locations/LocationForm/useLocationForm.js +5 -4
  28. package/dist/components/Company/Locations/LocationForm/useLocationForm.js.map +1 -1
  29. package/dist/components/Company/Locations/LocationsList/useLocationsList.js +5 -4
  30. package/dist/components/Company/Locations/LocationsList/useLocationsList.js.map +1 -1
  31. package/dist/components/Company/OnboardingOverview/context.js +5 -4
  32. package/dist/components/Company/OnboardingOverview/context.js.map +1 -1
  33. package/dist/components/Company/PaySchedule/PaySchedule.js +45 -30
  34. package/dist/components/Company/PaySchedule/PaySchedule.js.map +1 -1
  35. package/dist/components/Company/PaySchedule/PayScheduleComponents.js +12 -11
  36. package/dist/components/Company/PaySchedule/PayScheduleComponents.js.map +1 -1
  37. package/dist/components/Company/PaySchedule/PayScheduleForm.js +72 -55
  38. package/dist/components/Company/PaySchedule/PayScheduleForm.js.map +1 -1
  39. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/fields.js +24 -20
  40. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/fields.js.map +1 -1
  41. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/payScheduleSchema.js +33 -29
  42. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/payScheduleSchema.js.map +1 -1
  43. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/usePayScheduleForm.js +131 -115
  44. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/usePayScheduleForm.js.map +1 -1
  45. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js +5 -4
  46. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js.map +1 -1
  47. package/dist/components/Company/StateTaxes/StateTaxesList/context.js +5 -4
  48. package/dist/components/Company/StateTaxes/StateTaxesList/context.js.map +1 -1
  49. package/dist/components/Company/StateTaxes/TaxRateManagement/context.js +5 -4
  50. package/dist/components/Company/StateTaxes/TaxRateManagement/context.js.map +1 -1
  51. package/dist/components/Contractor/ContractorList/management/ManagementContractorList.js +31 -29
  52. package/dist/components/Contractor/ContractorList/management/ManagementContractorList.js.map +1 -1
  53. package/dist/components/Contractor/ContractorList/management/ManagementContractorListView.js +110 -109
  54. package/dist/components/Contractor/ContractorList/management/ManagementContractorListView.js.map +1 -1
  55. package/dist/components/Contractor/ContractorList/onboarding/ContractorList.js +21 -19
  56. package/dist/components/Contractor/ContractorList/onboarding/ContractorList.js.map +1 -1
  57. package/dist/components/Contractor/ContractorList/onboarding/ContractorListView.js +56 -55
  58. package/dist/components/Contractor/ContractorList/onboarding/ContractorListView.js.map +1 -1
  59. package/dist/components/Contractor/Dashboard/Dashboard.js +34 -33
  60. package/dist/components/Contractor/Dashboard/Dashboard.js.map +1 -1
  61. package/dist/components/Contractor/Payments/CreateHistoricalPayment/CreateHistoricalPayment.js +117 -115
  62. package/dist/components/Contractor/Payments/CreateHistoricalPayment/CreateHistoricalPayment.js.map +1 -1
  63. package/dist/components/Contractor/Payments/CreatePayment/CreatePayment.js +77 -75
  64. package/dist/components/Contractor/Payments/CreatePayment/CreatePayment.js.map +1 -1
  65. package/dist/components/Contractor/Payments/CreatePayment/CreatePaymentPresentation.js +44 -43
  66. package/dist/components/Contractor/Payments/CreatePayment/CreatePaymentPresentation.js.map +1 -1
  67. package/dist/components/Contractor/Payments/CreatePayment/PreviewPresentation.js +40 -39
  68. package/dist/components/Contractor/Payments/CreatePayment/PreviewPresentation.js.map +1 -1
  69. package/dist/components/Contractor/Payments/HistoricalPaymentSummary/HistoricalPaymentSummary.js +35 -29
  70. package/dist/components/Contractor/Payments/HistoricalPaymentSummary/HistoricalPaymentSummary.js.map +1 -1
  71. package/dist/components/Contractor/Payments/PaymentHistory/PaymentHistory.js +21 -20
  72. package/dist/components/Contractor/Payments/PaymentHistory/PaymentHistory.js.map +1 -1
  73. package/dist/components/Contractor/Payments/PaymentHistory/PaymentHistoryPresentation.js +41 -40
  74. package/dist/components/Contractor/Payments/PaymentHistory/PaymentHistoryPresentation.js.map +1 -1
  75. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatement.js +21 -20
  76. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatement.js.map +1 -1
  77. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.js +33 -32
  78. package/dist/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.js.map +1 -1
  79. package/dist/components/Contractor/Payments/PaymentsList/PaymentsList.js +80 -78
  80. package/dist/components/Contractor/Payments/PaymentsList/PaymentsList.js.map +1 -1
  81. package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.js +44 -43
  82. package/dist/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.js.map +1 -1
  83. package/dist/components/Contractor/Submit/Submit.js +113 -105
  84. package/dist/components/Contractor/Submit/Submit.js.map +1 -1
  85. package/dist/components/Contractor/Submit/SubmitDone.js +11 -11
  86. package/dist/components/Contractor/Submit/SubmitDone.js.map +1 -1
  87. package/dist/components/Employee/Compensation/management/CompensationAddJobForm/CompensationAddJobForm.js +20 -18
  88. package/dist/components/Employee/Compensation/management/CompensationAddJobForm/CompensationAddJobForm.js.map +1 -1
  89. package/dist/components/Employee/Compensation/management/CompensationEditForm/CompensationEditForm.js +18 -15
  90. package/dist/components/Employee/Compensation/management/CompensationEditForm/CompensationEditForm.js.map +1 -1
  91. package/dist/components/Employee/Dashboard/Dashboard.js +33 -32
  92. package/dist/components/Employee/Dashboard/Dashboard.js.map +1 -1
  93. package/dist/components/Employee/Deductions/management/DeductionsEditForm/DeductionsEditForm.js +21 -19
  94. package/dist/components/Employee/Deductions/management/DeductionsEditForm/DeductionsEditForm.js.map +1 -1
  95. package/dist/components/Employee/Documents/management/DocumentManager.js +34 -26
  96. package/dist/components/Employee/Documents/management/DocumentManager.js.map +1 -1
  97. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js +5 -4
  98. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  99. package/dist/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibility.js +30 -29
  100. package/dist/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibility.js.map +1 -1
  101. package/dist/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilityPresentation.js +54 -53
  102. package/dist/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilityPresentation.js.map +1 -1
  103. package/dist/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocuments.js +29 -28
  104. package/dist/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocuments.js.map +1 -1
  105. package/dist/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocumentsPresentation.js +16 -15
  106. package/dist/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocumentsPresentation.js.map +1 -1
  107. package/dist/components/Employee/EmployeeList/management/ManagementEmployeeList.js +27 -25
  108. package/dist/components/Employee/EmployeeList/management/ManagementEmployeeList.js.map +1 -1
  109. package/dist/components/Employee/EmployeeList/management/ManagementEmployeeListView.js +89 -80
  110. package/dist/components/Employee/EmployeeList/management/ManagementEmployeeListView.js.map +1 -1
  111. package/dist/components/Employee/EmployeeList/onboarding/EmployeeList.js +22 -20
  112. package/dist/components/Employee/EmployeeList/onboarding/EmployeeList.js.map +1 -1
  113. package/dist/components/Employee/EmployeeList/onboarding/EmployeeListView.js +25 -24
  114. package/dist/components/Employee/EmployeeList/onboarding/EmployeeListView.js.map +1 -1
  115. package/dist/components/Employee/EmployeeList/shared/useEmployeeList.js +1 -1
  116. package/dist/components/Employee/EmployeeList/shared/useEmployeeList.js.map +1 -1
  117. package/dist/components/Employee/FederalTaxes/shared/FederalTaxesView.js +1 -1
  118. package/dist/components/Employee/HomeAddress/management/HomeAddressEditForm.js +19 -17
  119. package/dist/components/Employee/HomeAddress/management/HomeAddressEditForm.js.map +1 -1
  120. package/dist/components/Employee/HomeAddress/management/HomeAddressView.js +80 -79
  121. package/dist/components/Employee/HomeAddress/management/HomeAddressView.js.map +1 -1
  122. package/dist/components/Employee/PaymentMethod/management/PaymentMethodBankForm.js +4 -4
  123. package/dist/components/Employee/PaymentMethod/onboarding/BankForm.js +4 -4
  124. package/dist/components/Employee/Terminations/TerminateEmployee/TerminateEmployee.js +40 -39
  125. package/dist/components/Employee/Terminations/TerminateEmployee/TerminateEmployee.js.map +1 -1
  126. package/dist/components/Employee/Terminations/TerminateEmployee/TerminateEmployeePresentation.js +34 -33
  127. package/dist/components/Employee/Terminations/TerminateEmployee/TerminateEmployeePresentation.js.map +1 -1
  128. package/dist/components/Employee/Terminations/TerminationSummary/TerminationSummary.js +43 -41
  129. package/dist/components/Employee/Terminations/TerminationSummary/TerminationSummary.js.map +1 -1
  130. package/dist/components/Employee/Terminations/TerminationSummary/TerminationSummaryPresentation.js +22 -21
  131. package/dist/components/Employee/Terminations/TerminationSummary/TerminationSummaryPresentation.js.map +1 -1
  132. package/dist/components/Employee/WorkAddress/management/WorkAddressEditForm.js +19 -17
  133. package/dist/components/Employee/WorkAddress/management/WorkAddressEditForm.js.map +1 -1
  134. package/dist/components/Employee/WorkAddress/management/WorkAddressView.js +120 -116
  135. package/dist/components/Employee/WorkAddress/management/WorkAddressView.js.map +1 -1
  136. package/dist/components/Flow/Flow.js +1 -1
  137. package/dist/components/InformationRequests/InformationRequestList/InformationRequestList.js +29 -29
  138. package/dist/components/InformationRequests/InformationRequestList/InformationRequestList.js.map +1 -1
  139. package/dist/components/Payroll/ConfirmWireDetails/ConfirmWireDetails.js +37 -36
  140. package/dist/components/Payroll/ConfirmWireDetails/ConfirmWireDetails.js.map +1 -1
  141. package/dist/components/Payroll/ConfirmWireDetails/ConfirmWireDetailsBanner/ConfirmWireDetailsBanner.js +37 -36
  142. package/dist/components/Payroll/ConfirmWireDetails/ConfirmWireDetailsBanner/ConfirmWireDetailsBanner.js.map +1 -1
  143. package/dist/components/Payroll/Dismissal/DismissalPayPeriodSelection/DismissalPayPeriodSelection.js +35 -28
  144. package/dist/components/Payroll/Dismissal/DismissalPayPeriodSelection/DismissalPayPeriodSelection.js.map +1 -1
  145. package/dist/components/Payroll/Dismissal/DismissalPayPeriodSelection/DismissalPayPeriodSelectionPresentation.js +27 -26
  146. package/dist/components/Payroll/Dismissal/DismissalPayPeriodSelection/DismissalPayPeriodSelectionPresentation.js.map +1 -1
  147. package/dist/components/Payroll/GrossUpModal/GrossUpModal.js +2 -3
  148. package/dist/components/Payroll/GrossUpModal/GrossUpModal.js.map +1 -1
  149. package/dist/components/Payroll/OffCycleCreation/OffCycleCreation.js +52 -51
  150. package/dist/components/Payroll/OffCycleCreation/OffCycleCreation.js.map +1 -1
  151. package/dist/components/Payroll/OffCycleCreation/OffCycleCreationPresentation.js +34 -33
  152. package/dist/components/Payroll/OffCycleCreation/OffCycleCreationPresentation.js.map +1 -1
  153. package/dist/components/Payroll/OffCycleDeductionsSetting/OffCycleDeductionsSetting.js +23 -21
  154. package/dist/components/Payroll/OffCycleDeductionsSetting/OffCycleDeductionsSetting.js.map +1 -1
  155. package/dist/components/Payroll/OffCycleReasonSelection/OffCycleReasonSelection.js +26 -19
  156. package/dist/components/Payroll/OffCycleReasonSelection/OffCycleReasonSelection.js.map +1 -1
  157. package/dist/components/Payroll/OffCycleReasonSelection/OffCycleReasonSelectionPresentation.js +14 -12
  158. package/dist/components/Payroll/OffCycleReasonSelection/OffCycleReasonSelectionPresentation.js.map +1 -1
  159. package/dist/components/Payroll/PayrollConfiguration/PayrollConfiguration.js +112 -109
  160. package/dist/components/Payroll/PayrollConfiguration/PayrollConfiguration.js.map +1 -1
  161. package/dist/components/Payroll/PayrollConfiguration/PayrollConfigurationPresentation.js +67 -65
  162. package/dist/components/Payroll/PayrollConfiguration/PayrollConfigurationPresentation.js.map +1 -1
  163. package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployee.js +43 -41
  164. package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployee.js.map +1 -1
  165. package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.js +225 -223
  166. package/dist/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.js.map +1 -1
  167. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.js +78 -75
  168. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.js.map +1 -1
  169. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeHelpers.js +27 -27
  170. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeHelpers.js.map +1 -1
  171. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.js +19 -19
  172. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.js.map +1 -1
  173. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/usePayrollEditEmployeeForm.js +51 -48
  174. package/dist/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/usePayrollEditEmployeeForm.js.map +1 -1
  175. package/dist/components/Payroll/PayrollHistory/PayrollHistory.js +58 -48
  176. package/dist/components/Payroll/PayrollHistory/PayrollHistory.js.map +1 -1
  177. package/dist/components/Payroll/PayrollHistory/PayrollHistoryPresentation.js +58 -57
  178. package/dist/components/Payroll/PayrollHistory/PayrollHistoryPresentation.js.map +1 -1
  179. package/dist/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.js +83 -69
  180. package/dist/components/Payroll/PayrollLanding/PayrollLandingFlowComponents.js.map +1 -1
  181. package/dist/components/Payroll/PayrollList/PayrollList.js +62 -60
  182. package/dist/components/Payroll/PayrollList/PayrollList.js.map +1 -1
  183. package/dist/components/Payroll/PayrollList/PayrollListPresentation.js +119 -117
  184. package/dist/components/Payroll/PayrollList/PayrollListPresentation.js.map +1 -1
  185. package/dist/components/Payroll/PayrollOverview/PayrollOverview.js +101 -99
  186. package/dist/components/Payroll/PayrollOverview/PayrollOverview.js.map +1 -1
  187. package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.js +120 -110
  188. package/dist/components/Payroll/PayrollOverview/PayrollOverviewPresentation.js.map +1 -1
  189. package/dist/components/Payroll/PayrollReceipts/PayrollReceipts.js +20 -14
  190. package/dist/components/Payroll/PayrollReceipts/PayrollReceipts.js.map +1 -1
  191. package/dist/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.js +39 -38
  192. package/dist/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.js.map +1 -1
  193. package/dist/components/Payroll/PrintChecks/PrintChecksBanner/PrintChecksBanner.js +24 -17
  194. package/dist/components/Payroll/PrintChecks/PrintChecksBanner/PrintChecksBanner.js.map +1 -1
  195. package/dist/components/Payroll/PrintChecks/PrintChecksFailure/PrintChecksFailure.js +17 -17
  196. package/dist/components/Payroll/PrintChecks/PrintChecksFailure/PrintChecksFailure.js.map +1 -1
  197. package/dist/components/Payroll/PrintChecks/PrintChecksForm/PrintChecksForm.js +88 -80
  198. package/dist/components/Payroll/PrintChecks/PrintChecksForm/PrintChecksForm.js.map +1 -1
  199. package/dist/components/Payroll/PrintChecks/PrintChecksSummary/PrintChecksSummary.js +26 -26
  200. package/dist/components/Payroll/PrintChecks/PrintChecksSummary/PrintChecksSummary.js.map +1 -1
  201. package/dist/components/Payroll/RecoveryCases/RecoveryCasesResubmit/RecoveryCasesResubmit.js +32 -32
  202. package/dist/components/Payroll/RecoveryCases/RecoveryCasesResubmit/RecoveryCasesResubmit.js.map +1 -1
  203. package/dist/components/Payroll/TransitionCreation/TransitionCreation.js +50 -48
  204. package/dist/components/Payroll/TransitionCreation/TransitionCreation.js.map +1 -1
  205. package/dist/components/Payroll/TransitionCreation/TransitionCreationPresentation.js +34 -33
  206. package/dist/components/Payroll/TransitionCreation/TransitionCreationPresentation.js.map +1 -1
  207. package/dist/components/Payroll/TransitionCreation/TransitionCreationTypes.js.map +1 -1
  208. package/dist/components/Payroll/TransitionPayrollAlert/TransitionPayrollAlert.js +28 -24
  209. package/dist/components/Payroll/TransitionPayrollAlert/TransitionPayrollAlert.js.map +1 -1
  210. package/dist/components/Payroll/UNSTABLE_PayrollEditEmployee/UNSTABLE_PayrollEditEmployee.js +255 -228
  211. package/dist/components/Payroll/UNSTABLE_PayrollEditEmployee/UNSTABLE_PayrollEditEmployee.js.map +1 -1
  212. package/dist/components/Payroll/UNSTABLE_PayrollEditEmployee/UNSTABLE_PayrollEditEmployee.module.scss.js +8 -4
  213. package/dist/components/Payroll/UNSTABLE_PayrollEditEmployee/UNSTABLE_PayrollEditEmployee.module.scss.js.map +1 -1
  214. package/dist/components/Payroll/usePreparedPayrollData.js +4 -3
  215. package/dist/components/Payroll/usePreparedPayrollData.js.map +1 -1
  216. package/dist/components/TimeOff/AddEmployeesHoliday/AddEmployeesHoliday.js +5 -5
  217. package/dist/components/TimeOff/AddEmployeesHoliday/AddEmployeesHoliday.js.map +1 -1
  218. package/dist/components/TimeOff/AddEmployeesToPolicy/AddEmployeesToPolicy.js +8 -7
  219. package/dist/components/TimeOff/AddEmployeesToPolicy/AddEmployeesToPolicy.js.map +1 -1
  220. package/dist/components/TimeOff/HolidayPolicyDetail/HolidayPolicyDetail.js +51 -50
  221. package/dist/components/TimeOff/HolidayPolicyDetail/HolidayPolicyDetail.js.map +1 -1
  222. package/dist/components/TimeOff/HolidayPolicyDetail/HolidayPolicyDetailPresentation.js +20 -18
  223. package/dist/components/TimeOff/HolidayPolicyDetail/HolidayPolicyDetailPresentation.js.map +1 -1
  224. package/dist/components/TimeOff/HolidaySelectionForm/HolidaySelectionForm.js +51 -49
  225. package/dist/components/TimeOff/HolidaySelectionForm/HolidaySelectionForm.js.map +1 -1
  226. package/dist/components/TimeOff/HolidaySelectionForm/HolidaySelectionFormPresentation.js +20 -20
  227. package/dist/components/TimeOff/HolidaySelectionForm/HolidaySelectionFormPresentation.js.map +1 -1
  228. package/dist/components/TimeOff/PolicyList/PolicyList.js +50 -49
  229. package/dist/components/TimeOff/PolicyList/PolicyList.js.map +1 -1
  230. package/dist/components/TimeOff/PolicyList/PolicyListPresentation.js +34 -33
  231. package/dist/components/TimeOff/PolicyList/PolicyListPresentation.js.map +1 -1
  232. package/dist/components/TimeOff/PolicySettings/PolicySettings.js +46 -45
  233. package/dist/components/TimeOff/PolicySettings/PolicySettings.js.map +1 -1
  234. package/dist/components/TimeOff/PolicySettings/PolicySettingsPresentation.js +152 -143
  235. package/dist/components/TimeOff/PolicySettings/PolicySettingsPresentation.js.map +1 -1
  236. package/dist/components/TimeOff/PolicyTypeSelector/PolicyTypeSelector.js +14 -13
  237. package/dist/components/TimeOff/PolicyTypeSelector/PolicyTypeSelector.js.map +1 -1
  238. package/dist/components/TimeOff/PolicyTypeSelector/PolicyTypeSelectorPresentation.js +44 -35
  239. package/dist/components/TimeOff/PolicyTypeSelector/PolicyTypeSelectorPresentation.js.map +1 -1
  240. package/dist/components/TimeOff/TimeOffManagement/PolicyConfigurationForm/PolicyConfigurationForm.js +88 -71
  241. package/dist/components/TimeOff/TimeOffManagement/PolicyConfigurationForm/PolicyConfigurationForm.js.map +1 -1
  242. package/dist/components/TimeOff/TimeOffManagement/PolicyConfigurationForm/PolicyConfigurationFormPresentation.js +164 -155
  243. package/dist/components/TimeOff/TimeOffManagement/PolicyConfigurationForm/PolicyConfigurationFormPresentation.js.map +1 -1
  244. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesHoliday.js +57 -55
  245. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesHoliday.js.map +1 -1
  246. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.js +25 -24
  247. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.js.map +1 -1
  248. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesTimeOff.js +94 -92
  249. package/dist/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesTimeOff.js.map +1 -1
  250. package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetail.js +156 -155
  251. package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetail.js.map +1 -1
  252. package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailPresentation.js +21 -19
  253. package/dist/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailPresentation.js.map +1 -1
  254. package/dist/components/TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.js +28 -26
  255. package/dist/components/TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.js.map +1 -1
  256. package/dist/contexts/ComponentAdapter/useComponentContext.js.map +1 -1
  257. package/dist/contexts/UnstableFeaturesProvider/useUnstableFeature.js.map +1 -1
  258. package/dist/i18n/en/Company.PaySchedule.json.js +22 -20
  259. package/dist/i18n/en/Company.PaySchedule.json.js.map +1 -1
  260. package/dist/i18n/en/Payroll.UNSTABLE_PayrollEditEmployee.json.js +62 -58
  261. package/dist/i18n/en/Payroll.UNSTABLE_PayrollEditEmployee.json.js.map +1 -1
  262. package/dist/package.json.js +1 -1
  263. package/dist/src/components/Common/FieldCaption/FieldCaption.d.ts +2 -16
  264. package/dist/src/components/Common/FieldCaption/FieldCaptionTypes.d.ts +22 -0
  265. package/dist/src/components/Common/FieldCaption/index.d.ts +1 -0
  266. package/dist/src/components/Common/Flex/Flex.d.ts +3 -1
  267. package/dist/src/components/Company/PaySchedule/PaySchedule.d.ts +10 -2
  268. package/dist/src/components/Company/PaySchedule/PayScheduleComponents.d.ts +1 -0
  269. package/dist/src/components/Company/PaySchedule/shared/usePayScheduleForm/fields.d.ts +9 -1
  270. package/dist/src/components/Company/PaySchedule/shared/usePayScheduleForm/index.d.ts +2 -2
  271. package/dist/src/components/Company/PaySchedule/shared/usePayScheduleForm/payScheduleSchema.d.ts +21 -5
  272. package/dist/src/components/Company/PaySchedule/shared/usePayScheduleForm/usePayScheduleForm.d.ts +21 -3
  273. package/dist/src/components/Contractor/ContractorList/management/ManagementContractorListView.d.ts +3 -1
  274. package/dist/src/components/Contractor/ContractorList/onboarding/ContractorListView.d.ts +3 -1
  275. package/dist/src/components/Contractor/Payments/CreatePayment/CreatePaymentPresentation.d.ts +3 -1
  276. package/dist/src/components/Contractor/Payments/CreatePayment/PreviewPresentation.d.ts +3 -1
  277. package/dist/src/components/Contractor/Payments/PaymentHistory/PaymentHistoryPresentation.d.ts +3 -1
  278. package/dist/src/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.d.ts +3 -1
  279. package/dist/src/components/Contractor/Payments/PaymentsList/PaymentsListPresentation.d.ts +3 -1
  280. package/dist/src/components/Contractor/Submit/SubmitDone.d.ts +3 -1
  281. package/dist/src/components/Employee/Compensation/management/CompensationEditForm/CompensationEditForm.d.ts +1 -1
  282. package/dist/src/components/Employee/Documents/onboarding/DocumentSigner/EmploymentEligibility/EmploymentEligibilityPresentation.d.ts +3 -1
  283. package/dist/src/components/Employee/Documents/onboarding/EmployeeDocuments/EmployeeDocumentsPresentation.d.ts +3 -1
  284. package/dist/src/components/Employee/EmployeeList/management/ManagementEmployeeListView.d.ts +3 -1
  285. package/dist/src/components/Employee/EmployeeList/onboarding/EmployeeListView.d.ts +3 -1
  286. package/dist/src/components/Employee/EmployeeList/shared/useEmployeeList.d.ts +4 -0
  287. package/dist/src/components/Employee/HomeAddress/management/HomeAddressView.d.ts +3 -1
  288. package/dist/src/components/Employee/Terminations/TerminateEmployee/TerminateEmployeePresentation.d.ts +3 -1
  289. package/dist/src/components/Employee/Terminations/TerminationSummary/TerminationSummaryPresentation.d.ts +3 -1
  290. package/dist/src/components/Employee/WorkAddress/management/WorkAddressView.d.ts +3 -1
  291. package/dist/src/components/Payroll/Dismissal/DismissalPayPeriodSelection/DismissalPayPeriodSelectionPresentation.d.ts +3 -1
  292. package/dist/src/components/Payroll/OffCycleCreation/OffCycleCreationPresentation.d.ts +1 -1
  293. package/dist/src/components/Payroll/OffCycleCreation/OffCycleCreationTypes.d.ts +2 -0
  294. package/dist/src/components/Payroll/OffCycleReasonSelection/OffCycleReasonSelectionPresentation.d.ts +3 -1
  295. package/dist/src/components/Payroll/PayrollConfiguration/PayrollConfigurationPresentation.d.ts +3 -1
  296. package/dist/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.d.ts +3 -1
  297. package/dist/src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.d.ts +9 -9
  298. package/dist/src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeHelpers.d.ts +2 -2
  299. package/dist/src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.d.ts +4 -4
  300. package/dist/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.d.ts +3 -1
  301. package/dist/src/components/Payroll/PayrollList/PayrollListPresentation.d.ts +3 -1
  302. package/dist/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.d.ts +2 -1
  303. package/dist/src/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.d.ts +2 -1
  304. package/dist/src/components/Payroll/TransitionCreation/TransitionCreationPresentation.d.ts +1 -1
  305. package/dist/src/components/Payroll/TransitionCreation/TransitionCreationTypes.d.ts +2 -0
  306. package/dist/src/components/Payroll/TransitionPayrollAlert/TransitionPayrollAlert.d.ts +3 -1
  307. package/dist/src/components/Payroll/UNSTABLE_PayrollEditEmployee/UNSTABLE_PayrollEditEmployee.d.ts +1 -1
  308. package/dist/src/components/TimeOff/AddEmployeesHoliday/AddEmployeesHoliday.d.ts +1 -1
  309. package/dist/src/components/TimeOff/AddEmployeesToPolicy/AddEmployeesToPolicy.d.ts +1 -1
  310. package/dist/src/components/TimeOff/HolidayPolicyDetail/HolidayPolicyDetailPresentation.d.ts +1 -1
  311. package/dist/src/components/TimeOff/HolidayPolicyDetail/HolidayPolicyDetailTypes.d.ts +2 -0
  312. package/dist/src/components/TimeOff/HolidaySelectionForm/HolidaySelectionFormTypes.d.ts +2 -0
  313. package/dist/src/components/TimeOff/PolicyList/PolicyListPresentation.d.ts +1 -1
  314. package/dist/src/components/TimeOff/PolicyList/PolicyListTypes.d.ts +2 -0
  315. package/dist/src/components/TimeOff/PolicySettings/PolicySettingsPresentation.d.ts +1 -1
  316. package/dist/src/components/TimeOff/PolicySettings/PolicySettingsTypes.d.ts +2 -0
  317. package/dist/src/components/TimeOff/PolicyTypeSelector/PolicyTypeSelectorPresentation.d.ts +1 -1
  318. package/dist/src/components/TimeOff/PolicyTypeSelector/PolicyTypeSelectorTypes.d.ts +2 -0
  319. package/dist/src/components/TimeOff/TimeOffManagement/PolicyConfigurationForm/PolicyConfigurationFormPresentation.d.ts +1 -1
  320. package/dist/src/components/TimeOff/TimeOffManagement/PolicyConfigurationForm/PolicyConfigurationFormTypes.d.ts +2 -0
  321. package/dist/src/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesHoliday.d.ts +2 -0
  322. package/dist/src/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentation.d.ts +1 -1
  323. package/dist/src/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesPresentationTypes.d.ts +2 -0
  324. package/dist/src/components/TimeOff/TimeOffManagement/SelectEmployees/SelectEmployeesTimeOff.d.ts +2 -0
  325. package/dist/src/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailPresentation.d.ts +1 -1
  326. package/dist/src/components/TimeOff/TimeOffPolicyDetail/TimeOffPolicyDetailTypes.d.ts +3 -0
  327. package/dist/src/components/TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.d.ts +1 -1
  328. package/dist/src/components/TimeOff/shared/PolicyDetailLayout/PolicyDetailLayoutTypes.d.ts +2 -0
  329. package/dist/src/contexts/ComponentAdapter/componentAdapterTypes.d.ts +1 -0
  330. package/dist/src/contexts/ComponentAdapter/useComponentContext.d.ts +4 -1
  331. package/dist/src/contexts/UnstableFeaturesProvider/useUnstableFeature.d.ts +4 -1
  332. package/dist/src/i18n/types.d.ts +28 -2
  333. package/dist/src/index.d.ts +1 -1
  334. package/dist/src/models/external.d.ts +1 -0
  335. package/dist/style.css +1 -1
  336. package/package.json +16 -15
@@ -1 +1 @@
1
- {"version":3,"file":"fields.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollUpdatePaymentMethod } from '@gusto/embedded-api/models/components/payrollupdate'\nimport type { NormalizedWorkweek } from './payrollEditEmployeeHelpers'\nimport type { PayrollEditEmployeeErrorCode } from './payrollEditEmployeeSchema'\nimport { TextInputField } from '@/components/Common/Fields/TextInputField/TextInputField'\nimport { useFieldErrorMessage } from '@/partner-hook-utils/form/useFieldErrorMessage'\nimport { RadioGroupHookField } from '@/partner-hook-utils/form/fields'\nimport type { RadioGroupHookFieldProps } from '@/partner-hook-utils/form/fields/RadioGroupHookField'\nimport type { HookFieldProps, ValidationMessages } from '@/partner-hook-utils/types'\nimport type { TextInputProps } from '@/components/Common/UI/TextInput/TextInputTypes'\nimport { PayrollCategory } from '@/components/Payroll/payrollTypes'\nimport { COMPENSATION_NAME_DOUBLE_OVERTIME, COMPENSATION_NAME_OVERTIME } from '@/shared/constants'\n\n/**\n * Display copy for each validation error code a bound field can surface, so the\n * consumer supplies error text once (keyed by code) rather than reconstructing\n * form paths or hardcoding which rule each field can fail. Partial: a missing\n * code falls back to the raw error code.\n *\n * @public\n */\nexport type PayrollEditEmployeeErrorMessages = Partial<Record<PayrollEditEmployeeErrorCode, string>>\n\n/**\n * Presentation props accepted by a bound numeric field in the payroll editor.\n *\n * @remarks\n * The hook binds the react-hook-form `name`, forces `type=\"number\"`, and\n * resolves the field's own validation message internally; the UI supplies copy\n * and layout props (label, adornments, `shouldVisuallyHideLabel`, required\n * state, `description`).\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type' | 'min' | 'errorMessage'\n>\n\n/**\n * A numeric field component pre-bound by the hook to a specific form path.\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldComponent = ComponentType<PayrollEditEmployeeFieldProps>\n\n/**\n * Presentation props accepted by the bound payment-method field.\n *\n * @remarks\n * The hook binds the `name` and publishes the option values on\n * `fieldsMetadata.paymentMethod`; the UI passes `getOptionLabel` to translate\n * each {@link PayrollUpdatePaymentMethod} value, rather than passing `options`.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodFieldProps = HookFieldProps<\n RadioGroupHookFieldProps<never, PayrollUpdatePaymentMethod>\n>\n\n/**\n * The payment-method radio field component pre-bound by the hook.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodField =\n ComponentType<PayrollEditEmployeePaymentMethodFieldProps>\n\n/**\n * One hours input within the hours section.\n *\n * @remarks\n * `key` is an opaque, stable React key. `jobUuid`, `name`, and (when the pay\n * period is multi-workweek) `workweekStart` are reach-in handles the UI uses to\n * group and label entries. When the section is a flat array, `workweekStart` is\n * omitted (single-workweek degenerate case); when it is a `Record` keyed by\n * workweek start, each entry carries its `workweekStart`.\n *\n * @public\n */\nexport interface HourEntry {\n /** Opaque, stable React key. */\n key: string\n /** The job this hours line belongs to. */\n jobUuid: string\n /** The compensation name (e.g. the API hours-compensation name). */\n name: string\n /** The workweek start date (`YYYY-MM-DD`) when the section is workweek-keyed. */\n workweekStart?: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * One earning input, used by the additional-earnings section.\n *\n * @remarks\n * Same shape as {@link HourEntry}. Whether an earning feeds the overtime\n * (regular rate of pay) calculation is decided by the hook, which sorts it into\n * the workweek-breakdown additional-earnings section or the flat other\n * section. The UI just renders whichever section an entry appears in.\n *\n * @public\n */\nexport type EarningEntry = HourEntry\n\n/**\n * One time-off or final-payout input.\n *\n * @remarks\n * Time off is never workweek-breakdown, so this section is always a flat array.\n *\n * @public\n */\nexport interface TimeOffEntry {\n /** Opaque, stable React key. */\n key: string\n /** The time-off policy compensation name. */\n name: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n /**\n * The policy's remaining balance after the entered hours are subtracted,\n * recomputed live as the user edits. `null` when the policy has no tracked\n * accrual balance (e.g. final-payout rows). Feed it into the field's own\n * `description` to render it as the input's help text.\n */\n remaining: number | null\n}\n\n/**\n * One entry in the flat `other` section.\n *\n * @remarks\n * Intentionally opaque: `other` collects earnings that are not overtime-affecting\n * and whose input type the partner does not need to reason about. Render each\n * entry's `Field` keyed by `key`; use `id` as a reach-in handle for labeling.\n *\n * @public\n */\nexport interface OtherEntry {\n /** Opaque, stable React key. */\n key: string\n /** Reach-in handle identifying the underlying earning (its compensation name). */\n id: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A single job's hours section.\n *\n * @remarks\n * An employee can hold multiple jobs, each with its own hourly lines. `hours` is\n * either a flat `Entry[]` (single-workweek, or an overtime-ineligible employee)\n * OR a `Record<workweekStart, Entry[]>` (multi-workweek and overtime-eligible).\n * The value type is the signal — array is flat, object is split by workweek; use\n * {@link isSplitByWorkweek} to discriminate. `title` is the job's display title\n * (entity data, not copy) for rendering a per-job heading. Earnings are not\n * job-scoped: they live in the employee-level `additionalEarnings` and\n * `otherEarnings` sections on {@link PayrollEditEmployeeFields}.\n *\n * @public\n */\nexport interface JobFields {\n /** The job identifier. */\n jobUuid: string\n /** The job's display title, when available, for a per-job heading. */\n title?: string\n /**\n * Hours inputs for this job. Excludes Overtime/Double-overtime rows while\n * `data.withOvertime` is `false`.\n */\n hours: HourEntry[] | Record<string, HourEntry[]>\n}\n\n/**\n * Presentation props accepted by a bound reimbursement description (text) field.\n *\n * @remarks\n * The hook binds the react-hook-form `name` internally; the UI supplies copy and\n * layout props (label, placeholder, `shouldVisuallyHideLabel`).\n *\n * @public\n */\nexport type ReimbursementDescriptionFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type'\n>\n\n/**\n * The draft \"add reimbursement\" field group exposed on\n * `form.Fields.reimbursementDraft`.\n *\n * @remarks\n * A single in-progress row the UI reveals when the user starts adding a\n * reimbursement. `Description` and `Amount` bind to `reimbursementDraft.description`\n * / `reimbursementDraft.amount`. The UI shows them while `form.reimbursementDraft.isAdding`\n * is `true`, then calls `actions.saveReimbursement` (commits to the list) or\n * `actions.cancelReimbursement` (discards). Committed rows are rendered from\n * `data.reimbursements`, not from bound fields.\n *\n * @public\n */\nexport interface ReimbursementDraftFields {\n /** Description field pre-bound to the draft's form path. */\n Description: ComponentType<ReimbursementDescriptionFieldProps>\n /** Amount field pre-bound to the draft's form path. */\n Amount: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A committed reimbursement row for display in the consumer's table.\n *\n * @remarks\n * Exposed on `data.reimbursements`, seeded from the employee's existing\n * reimbursements and appended to as the user saves drafts. Display-only: the UI\n * renders `description`, `amount`, and the recurring/one-time `type`, plus a\n * remove control wired to `actions.removeReimbursement(index)`. `index` is the\n * row's position in the underlying form array (the removal handle); `uuid` is\n * present for rows that already exist server-side.\n *\n * @public\n */\nexport interface ReimbursementRow {\n /** Opaque, stable React key. */\n key: string\n /** The row's index in the reimbursements form array; pass to `removeReimbursement`. */\n index: number\n /** The reimbursement's server UUID, when it already exists. */\n uuid?: string\n /** The reimbursement description (may be blank; the UI supplies a fallback). */\n description: string\n /** The reimbursement amount as a decimal string. */\n amount: string\n /** Whether this reimbursement recurs. Recurring rows are managed outside payroll. */\n recurring: boolean\n}\n\n/**\n * The render-ready field collections exposed on `form.Fields`.\n *\n * @remarks\n * Hours are grouped under `jobs`, one entry per job, so multi-job employees\n * render correctly. All earnings and the remaining sections are employee-scoped\n * and stay top-level: `additionalEarnings` (overtime-affecting) and\n * `otherEarnings` (non-overtime) each render as a single section spanning every\n * job, alongside time off, final payout, payment method, and reimbursements.\n *\n * @public\n */\nexport interface PayrollEditEmployeeFields {\n /** Per-job hours sections; one entry per job. */\n jobs: JobFields[]\n /**\n * Overtime-affecting earnings across all jobs, as a single employee-level\n * section. Flat `Entry[]` when unsplit, or `Record<workweekStart, Entry[]>`\n * when split by workweek; use {@link isSplitByWorkweek} to discriminate.\n */\n additionalEarnings: EarningEntry[] | Record<string, EarningEntry[]>\n /** Non-overtime earnings (e.g. tips), always flat; opaque render entries. */\n otherEarnings: OtherEntry[]\n /** Time-off inputs (never workweek-breakdown). */\n timeOff: TimeOffEntry[]\n /** Final-payout inputs, present only for dismissal payrolls. */\n finalPayout?: TimeOffEntry[]\n /** Payment-method selector, present only when the employee has direct deposit set up. */\n paymentMethod?: PayrollEditEmployeePaymentMethodField\n /**\n * The draft \"add reimbursement\" field group, present only for itemized\n * (non-off-cycle) payrolls. Render while `form.reimbursementDraft.isAdding` is\n * `true`; committed rows come from `data.reimbursements`.\n */\n reimbursementDraft?: ReimbursementDraftFields\n}\n\n/**\n * Discriminates a workweek-breakdown section: `false` for the flat\n * (single-workweek) `Entry[]` form, `true` for the workweek-keyed\n * `Record<workweekStart, Entry[]>` form.\n *\n * @typeParam TEntry - The section's entry type.\n * @param section - A `form.Fields` section that may be flat or workweek-keyed.\n * @returns `true` when the section is keyed by workweek start date.\n * @public\n */\nexport function isSplitByWorkweek<TEntry>(\n section: TEntry[] | Record<string, TEntry[]>,\n): section is Record<string, TEntry[]> {\n return !Array.isArray(section)\n}\n\n// ── Bound field factories ──────────────────────────────────────────────\n\nfunction createNumberField(\n name: string,\n errorMessages?: PayrollEditEmployeeErrorMessages,\n): PayrollEditEmployeeFieldComponent {\n return function BoundNumberField(props: PayrollEditEmployeeFieldProps) {\n // The field resolves its own validation copy from its bound path, so the\n // consumer supplies error copy once (keyed by code) and never reconstructs\n // form paths or guesses which rule a field can fail. name, type, min, and\n // errorMessage are applied after the spread so callers can't override the\n // binding or the non-negative numeric contract via custom props.\n const errorMessage = useFieldErrorMessage(\n name,\n errorMessages as ValidationMessages<PayrollEditEmployeeErrorCode> | undefined,\n )\n return (\n <TextInputField {...props} name={name} type=\"number\" min={0} errorMessage={errorMessage} />\n )\n }\n}\n\nfunction createPaymentMethodField(): PayrollEditEmployeePaymentMethodField {\n return function BoundPaymentMethodField(props: PayrollEditEmployeePaymentMethodFieldProps) {\n return (\n <RadioGroupHookField<never, PayrollUpdatePaymentMethod> {...props} name=\"paymentMethod\" />\n )\n }\n}\n\nfunction createTextField(name: string): ComponentType<ReimbursementDescriptionFieldProps> {\n return function BoundTextField(props: ReimbursementDescriptionFieldProps) {\n return <TextInputField {...props} name={name} />\n }\n}\n\n/**\n * Builds the draft \"add reimbursement\" field group, binding its Description and\n * Amount fields to the `reimbursementDraft` form path.\n *\n * @param errorMessages - Copy for each validation error code, baked into the amount field so it self-resolves.\n * @returns The pre-bound draft field group for `form.Fields.reimbursementDraft`.\n * @internal\n */\nexport function createReimbursementDraftFields(\n errorMessages?: PayrollEditEmployeeErrorMessages,\n): ReimbursementDraftFields {\n return {\n Description: createTextField('reimbursementDraft.description'),\n Amount: createNumberField('reimbursementDraft.amount', errorMessages),\n }\n}\n\n// ── Builders ───────────────────────────────────────────────────────────\n\n/** @internal */\nexport interface CreatePayrollEditEmployeeFieldsOptions {\n employeeCompensation: PayrollEmployeeCompensationsType | undefined\n /**\n * Fixed compensations to render, already merged with blank placeholders for\n * every company earning type (see `resolveEditableFixedCompensations`).\n */\n fixedCompensations: NonNullable<PayrollEmployeeCompensationsType['fixedCompensations']>\n workweeks: NormalizedWorkweek[]\n payrollCategory: PayrollCategory\n hasDirectDepositSetup: boolean\n /** Names of earning types included in the regular-rate-of-pay overtime calculation. */\n overtimeEarningNames: Set<string>\n /** Whether the employee is overtime-eligible (nonexempt family). Gates per-workweek splitting. */\n isOvertimeEligible: boolean\n /**\n * Gates per-workweek splitting\n * alongside `isOvertimeEligible`, and whether Overtime/Double-overtime rows\n * are included in `hours`.\n */\n withOvertime: boolean\n /** Job title lookup by job UUID, for per-job section headings. */\n jobTitlesByUuid: Map<string, string>\n /** Accrual balance by time-off policy name, for the remaining-balance display. */\n timeOffAccrualByName: Map<string, string>\n /** Copy for each validation error code, baked into every bound field so it self-resolves. */\n errorMessages?: PayrollEditEmployeeErrorMessages\n}\n\n/**\n * A time-off policy's remaining balance: its accrual balance minus the entered\n * hours. `null` when the policy has no tracked accrual balance (final-payout\n * rows). Shared by the field builder (seeding the initial value) and the hook\n * (recomputing it live as the user edits).\n *\n * @param accrualBalance - The policy's accrual balance, or `undefined` when untracked.\n * @param enteredHours - The currently entered hours for the policy.\n * @returns The remaining balance, or `null` when untracked.\n * @internal\n */\nexport function computeTimeOffRemaining(\n accrualBalance: string | undefined,\n enteredHours: string | null | undefined,\n): number | null {\n if (accrualBalance == null) return null\n return parseFloat(accrualBalance) - (parseFloat(enteredHours ?? '') || 0)\n}\n\nfunction buildBreakdownSection(\n compensations: Array<{ jobUuid?: string; name?: string }>,\n workweeks: NormalizedWorkweek[],\n pathPrefix: 'hours' | 'additionalEarnings',\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n errorMessages: PayrollEditEmployeeErrorMessages | undefined,\n): HourEntry[] | Record<string, HourEntry[]> {\n const rows = compensations.filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n\n const toEntry = (\n row: { jobUuid: string; name: string },\n weekStart: string,\n includeWorkweek: boolean,\n ): HourEntry => ({\n key: includeWorkweek ? `${row.jobUuid}:${row.name}:${weekStart}` : `${row.jobUuid}:${row.name}`,\n jobUuid: row.jobUuid,\n name: row.name,\n ...(includeWorkweek ? { workweekStart: weekStart } : {}),\n Field: createNumberField(\n `${pathPrefix}.${row.jobUuid}.${row.name}.${weekStart}`,\n errorMessages,\n ),\n })\n\n // Split into per-workweek columns only for overtime-eligible employees while\n // `withOvertime` is on; workweek breakdowns exist solely to compute overtime\n // premiums, so an ineligible employee renders flat even on a multi-workweek\n // payroll, and an eligible one stays flat until `withOvertime` is set.\n if (workweeks.length > 1 && isOvertimeEligible && withOvertime) {\n const byWeek: Record<string, HourEntry[]> = {}\n for (const workweek of workweeks) {\n byWeek[workweek.startDate] = rows.map(row => toEntry(row, workweek.startDate, true))\n }\n return byWeek\n }\n\n const weekStart = workweeks[0]?.startDate ?? ''\n return rows.map(row => toEntry(row, weekStart, false))\n}\n\n/**\n * Builds the render-ready {@link PayrollEditEmployeeFields} from the prepared\n * compensation.\n *\n * @remarks\n * Hours and overtime-affecting earnings are grouped per job into `jobs` (a job\n * appears if it has hourly lines or overtime-affecting earnings). Fixed\n * compensations are split by whether their earning type is included in the\n * regular-rate-of-pay overtime calculation (`overtimeEarningNames`): included\n * earnings become each job's additional earnings, the rest become the flat,\n * employee-level `other` section. Time off comes from the paid-time-off list,\n * final payout is added only for dismissal payrolls, and the payment-method\n * selector appears only when direct deposit is set up.\n *\n * @param options - The prepared compensation, normalized workweeks, payroll category, direct-deposit flag, overtime earning names, eligibility, the `withOvertime` flag, job titles, time-off accrual balances and entered values, and error copy.\n * @returns The populated field collections.\n * @internal\n */\nexport function createPayrollEditEmployeeFields({\n employeeCompensation,\n fixedCompensations,\n workweeks,\n payrollCategory,\n hasDirectDepositSetup,\n overtimeEarningNames,\n isOvertimeEligible,\n withOvertime,\n jobTitlesByUuid,\n timeOffAccrualByName,\n errorMessages,\n}: CreatePayrollEditEmployeeFieldsOptions): PayrollEditEmployeeFields {\n const hourlyCompensations = employeeCompensation?.hourlyCompensations ?? []\n const overtimeAffecting = fixedCompensations.filter(\n compensation => compensation.name != null && overtimeEarningNames.has(compensation.name),\n )\n const nonOvertime = fixedCompensations.filter(\n compensation => compensation.name == null || !overtimeEarningNames.has(compensation.name),\n )\n\n // A job appears if it has hourly lines or overtime-affecting earnings, in first\n // appearance order across those two sources.\n const jobUuids: string[] = []\n for (const compensation of [...hourlyCompensations, ...overtimeAffecting]) {\n if (compensation.jobUuid && !jobUuids.includes(compensation.jobUuid)) {\n jobUuids.push(compensation.jobUuid)\n }\n }\n\n const isOvertimeName = (name: string | null | undefined) =>\n name === COMPENSATION_NAME_OVERTIME || name === COMPENSATION_NAME_DOUBLE_OVERTIME\n\n const jobs: JobFields[] = jobUuids.map(jobUuid => {\n const jobHourlyCompensations = hourlyCompensations.filter(\n compensation => compensation.jobUuid === jobUuid,\n )\n // Overtime/Double-overtime rows stay out of `hours` entirely while\n // `withOvertime` is off — their underlying form values are untouched\n // (still whatever the prepared compensation carried), so hiding the row\n // can't lose or corrupt data. Driven by the single, employee-level flag —\n // no per-job hidden state.\n const visibleHourlyCompensations = withOvertime\n ? jobHourlyCompensations\n : jobHourlyCompensations.filter(compensation => !isOvertimeName(compensation.name))\n\n return {\n jobUuid,\n title: jobTitlesByUuid.get(jobUuid),\n hours: buildBreakdownSection(\n visibleHourlyCompensations,\n workweeks,\n 'hours',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n ),\n }\n })\n\n // Overtime-affecting earnings render as one employee-level section spanning\n // every job. Each entry keeps its per-job form path\n // (`additionalEarnings.<jobUuid>.<name>`), so the flat section still binds and\n // submits per job.\n const additionalEarnings = buildBreakdownSection(\n overtimeAffecting,\n workweeks,\n 'additionalEarnings',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n )\n\n const otherEarnings: OtherEntry[] = nonOvertime\n .filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n .map(compensation => ({\n key: `${compensation.jobUuid}:${compensation.name}`,\n id: compensation.name,\n Field: createNumberField(`other.${compensation.jobUuid}.${compensation.name}`, errorMessages),\n }))\n\n const timeOffRows = (employeeCompensation?.paidTimeOff ?? []).filter(entry => entry.name)\n const timeOff: TimeOffEntry[] = timeOffRows.map(entry => ({\n key: `timeOff:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`timeOff.${entry.name!}`, errorMessages),\n // Seeded from the initial entered hours; the hook recomputes it live.\n remaining: computeTimeOffRemaining(timeOffAccrualByName.get(entry.name!), entry.hours),\n }))\n\n // Final-payout rows never show a remaining balance.\n const finalPayout =\n payrollCategory === PayrollCategory.Dismissal\n ? timeOffRows.map(entry => ({\n key: `finalPayout:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`finalPayout.${entry.name!}`, errorMessages),\n remaining: null,\n }))\n : undefined\n\n return {\n jobs,\n additionalEarnings,\n otherEarnings,\n timeOff,\n finalPayout,\n paymentMethod: hasDirectDepositSetup ? createPaymentMethodField() : undefined,\n }\n}\n"],"names":["isSplitByWorkweek","section","createNumberField","name","errorMessages","props","errorMessage","useFieldErrorMessage","jsx","TextInputField","createPaymentMethodField","RadioGroupHookField","createTextField","createReimbursementDraftFields","computeTimeOffRemaining","accrualBalance","enteredHours","buildBreakdownSection","compensations","workweeks","pathPrefix","isOvertimeEligible","withOvertime","rows","compensation","toEntry","row","weekStart","includeWorkweek","byWeek","workweek","createPayrollEditEmployeeFields","employeeCompensation","fixedCompensations","payrollCategory","hasDirectDepositSetup","overtimeEarningNames","jobTitlesByUuid","timeOffAccrualByName","hourlyCompensations","overtimeAffecting","nonOvertime","jobUuids","isOvertimeName","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","jobs","jobUuid","jobHourlyCompensations","visibleHourlyCompensations","additionalEarnings","otherEarnings","timeOffRows","entry","timeOff","finalPayout","PayrollCategory"],"mappings":"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"}
1
+ {"version":3,"file":"fields.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/fields.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\nimport type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { PayrollUpdatePaymentMethod } from '@gusto/embedded-api/models/components/payrollupdate'\nimport type { NormalizedWorkweek } from './payrollEditEmployeeHelpers'\nimport type { PayrollEditEmployeeErrorCode } from './payrollEditEmployeeSchema'\nimport { TextInputField } from '@/components/Common/Fields/TextInputField/TextInputField'\nimport { useFieldErrorMessage } from '@/partner-hook-utils/form/useFieldErrorMessage'\nimport { RadioGroupHookField } from '@/partner-hook-utils/form/fields'\nimport type { RadioGroupHookFieldProps } from '@/partner-hook-utils/form/fields/RadioGroupHookField'\nimport type { HookFieldProps, ValidationMessages } from '@/partner-hook-utils/types'\nimport type { TextInputProps } from '@/components/Common/UI/TextInput/TextInputTypes'\nimport { PayrollCategory } from '@/components/Payroll/payrollTypes'\nimport { COMPENSATION_NAME_DOUBLE_OVERTIME, COMPENSATION_NAME_OVERTIME } from '@/shared/constants'\n\n/**\n * Display copy for each validation error code a bound field can surface, so the\n * consumer supplies error text once (keyed by code) rather than reconstructing\n * form paths or hardcoding which rule each field can fail. Partial: a missing\n * code falls back to the raw error code.\n *\n * @public\n */\nexport type PayrollEditEmployeeErrorMessages = Partial<Record<PayrollEditEmployeeErrorCode, string>>\n\n/**\n * Presentation props accepted by a bound numeric field in the payroll editor.\n *\n * @remarks\n * The hook binds the react-hook-form `name`, forces `type=\"number\"`, and\n * resolves the field's own validation message internally; the UI supplies copy\n * and layout props (label, adornments, `shouldVisuallyHideLabel`, required\n * state, `description`).\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type' | 'min' | 'errorMessage'\n>\n\n/**\n * A numeric field component pre-bound by the hook to a specific form path.\n *\n * @public\n */\nexport type PayrollEditEmployeeFieldComponent = ComponentType<PayrollEditEmployeeFieldProps>\n\n/**\n * Presentation props accepted by the bound payment-method field.\n *\n * @remarks\n * The hook binds the `name` and publishes the option values on\n * `fieldsMetadata.paymentMethod`; the UI passes `getOptionLabel` to translate\n * each {@link PayrollUpdatePaymentMethod} value, rather than passing `options`.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodFieldProps = HookFieldProps<\n RadioGroupHookFieldProps<never, PayrollUpdatePaymentMethod>\n>\n\n/**\n * The payment-method radio field component pre-bound by the hook.\n *\n * @public\n */\nexport type PayrollEditEmployeePaymentMethodField =\n ComponentType<PayrollEditEmployeePaymentMethodFieldProps>\n\n/**\n * One hours input within the hours section.\n *\n * @remarks\n * `key` is an opaque, stable React key. `jobUuid`, `name`, and (when the pay\n * period is multi-workweek) `workweekStart` are reach-in handles the UI uses to\n * group and label entries. When the section is a flat array, `workweekStart` is\n * omitted (single-workweek degenerate case); when it is a `Record` keyed by\n * workweek start, each entry carries its `workweekStart`.\n *\n * @public\n */\nexport interface HourEntry {\n /** Opaque, stable React key. */\n key: string\n /** The job this hours line belongs to. */\n jobUuid: string\n /** The compensation name (e.g. the API hours-compensation name). */\n name: string\n /** The workweek start date (`YYYY-MM-DD`) when the section is workweek-keyed. */\n workweekStart?: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * One earning input, used by the additional-earnings section.\n *\n * @remarks\n * Same shape as {@link HourEntry}. Whether an earning feeds the overtime\n * (regular rate of pay) calculation is decided by the hook, which sorts it into\n * the workweek-breakdown additional-earnings section or the flat other\n * section. The UI just renders whichever section an entry appears in.\n *\n * @public\n */\nexport type EarningEntry = HourEntry\n\n/**\n * One time-off or final-payout input.\n *\n * @remarks\n * Time off is never workweek-breakdown, so this section is always a flat array.\n *\n * @public\n */\nexport interface TimeOffEntry {\n /** Opaque, stable React key. */\n key: string\n /** The time-off policy compensation name. */\n name: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n /**\n * The policy's remaining balance after the entered hours are subtracted,\n * recomputed live as the user edits. `null` when the policy has no tracked\n * accrual balance (e.g. final-payout rows). Feed it into the field's own\n * `description` to render it as the input's help text.\n */\n remaining: number | null\n}\n\n/**\n * One entry in the flat `overtimeExcludedEarnings` section.\n *\n * @remarks\n * Intentionally opaque: `overtimeExcludedEarnings` collects earnings that are not overtime-affecting\n * and whose input type the partner does not need to reason about. Render each\n * entry's `Field` keyed by `key`; use `id` as a reach-in handle for labeling.\n *\n * @public\n */\nexport interface OtherEntry {\n /** Opaque, stable React key. */\n key: string\n /** Reach-in handle identifying the underlying earning (its compensation name). */\n id: string\n /** Field component pre-bound to this entry's form path. */\n Field: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A single job's hours section.\n *\n * @remarks\n * An employee can hold multiple jobs, each with its own hourly lines. `hours` is\n * either a flat `Entry[]` (single-workweek, or an overtime-ineligible employee)\n * OR a `Record<workweekStart, Entry[]>` (multi-workweek and overtime-eligible).\n * The value type is the signal — array is flat, object is split by workweek; use\n * {@link isSplitByWorkweek} to discriminate. `title` is the job's display title\n * (entity data, not copy) for rendering a per-job heading. Earnings are not\n * job-scoped: they live in the employee-level `overtimeIncludedEarnings` and\n * `overtimeExcludedEarnings` sections on {@link PayrollEditEmployeeFields}.\n *\n * @public\n */\nexport interface JobFields {\n /** The job identifier. */\n jobUuid: string\n /** The job's display title, when available, for a per-job heading. */\n title?: string\n /**\n * Hours inputs for this job. Excludes Overtime/Double-overtime rows while\n * `data.withOvertime` is `false`.\n */\n hours: HourEntry[] | Record<string, HourEntry[]>\n}\n\n/**\n * Presentation props accepted by a bound reimbursement description (text) field.\n *\n * @remarks\n * The hook binds the react-hook-form `name` internally; the UI supplies copy and\n * layout props (label, placeholder, `shouldVisuallyHideLabel`).\n *\n * @public\n */\nexport type ReimbursementDescriptionFieldProps = Omit<\n TextInputProps,\n 'name' | 'value' | 'onChange' | 'isInvalid' | 'type'\n>\n\n/**\n * The draft \"add reimbursement\" field group exposed on\n * `form.Fields.reimbursementDraft`.\n *\n * @remarks\n * A single in-progress row the UI reveals when the user starts adding a\n * reimbursement. `Description` and `Amount` bind to `reimbursementDraft.description`\n * / `reimbursementDraft.amount`. The UI shows them while `form.reimbursementDraft.isAdding`\n * is `true`, then calls `actions.saveReimbursement` (commits to the list) or\n * `actions.cancelReimbursement` (discards). Committed rows are rendered from\n * `data.reimbursements`, not from bound fields.\n *\n * @public\n */\nexport interface ReimbursementDraftFields {\n /** Description field pre-bound to the draft's form path. */\n Description: ComponentType<ReimbursementDescriptionFieldProps>\n /** Amount field pre-bound to the draft's form path. */\n Amount: PayrollEditEmployeeFieldComponent\n}\n\n/**\n * A committed reimbursement row for display in the consumer's table.\n *\n * @remarks\n * Exposed on `data.reimbursements`, seeded from the employee's existing\n * reimbursements and appended to as the user saves drafts. Display-only: the UI\n * renders `description`, `amount`, and the recurring/one-time `type`, plus a\n * remove control wired to `actions.removeReimbursement(index)`. `index` is the\n * row's position in the underlying form array (the removal handle); `uuid` is\n * present for rows that already exist server-side.\n *\n * @public\n */\nexport interface ReimbursementRow {\n /** Opaque, stable React key. */\n key: string\n /** The row's index in the reimbursements form array; pass to `removeReimbursement`. */\n index: number\n /** The reimbursement's server UUID, when it already exists. */\n uuid?: string\n /** The reimbursement description (may be blank; the UI supplies a fallback). */\n description: string\n /** The reimbursement amount as a decimal string. */\n amount: string\n /** Whether this reimbursement recurs. Recurring rows are managed outside payroll. */\n recurring: boolean\n}\n\n/**\n * The render-ready field collections exposed on `form.Fields`.\n *\n * @remarks\n * Hours are grouped under `jobs`, one entry per job, so multi-job employees\n * render correctly. All earnings and the remaining sections are employee-scoped\n * and stay top-level: `overtimeIncludedEarnings` (overtime-affecting) and\n * `overtimeExcludedEarnings` (non-overtime) each render as a single section spanning every\n * job, alongside time off, final payout, payment method, and reimbursements.\n *\n * @public\n */\nexport interface PayrollEditEmployeeFields {\n /** Per-job hours sections; one entry per job. */\n jobs: JobFields[]\n /**\n * Overtime-affecting earnings across all jobs, as a single employee-level\n * section. Flat `Entry[]` when unsplit, or `Record<workweekStart, Entry[]>`\n * when split by workweek; use {@link isSplitByWorkweek} to discriminate.\n */\n overtimeIncludedEarnings: EarningEntry[] | Record<string, EarningEntry[]>\n /** Non-overtime earnings (e.g. tips), always flat; opaque render entries. */\n overtimeExcludedEarnings: OtherEntry[]\n /** Time-off inputs (never workweek-breakdown). */\n timeOff: TimeOffEntry[]\n /** Final-payout inputs, present only for dismissal payrolls. */\n finalPayout?: TimeOffEntry[]\n /** Payment-method selector, present only when the employee has direct deposit set up. */\n paymentMethod?: PayrollEditEmployeePaymentMethodField\n /**\n * The draft \"add reimbursement\" field group, present only for itemized\n * (non-off-cycle) payrolls. Render while `form.reimbursementDraft.isAdding` is\n * `true`; committed rows come from `data.reimbursements`.\n */\n reimbursementDraft?: ReimbursementDraftFields\n}\n\n/**\n * Discriminates a workweek-breakdown section: `false` for the flat\n * (single-workweek) `Entry[]` form, `true` for the workweek-keyed\n * `Record<workweekStart, Entry[]>` form.\n *\n * @typeParam TEntry - The section's entry type.\n * @param section - A `form.Fields` section that may be flat or workweek-keyed.\n * @returns `true` when the section is keyed by workweek start date.\n * @public\n */\nexport function isSplitByWorkweek<TEntry>(\n section: TEntry[] | Record<string, TEntry[]>,\n): section is Record<string, TEntry[]> {\n return !Array.isArray(section)\n}\n\n// ── Bound field factories ──────────────────────────────────────────────\n\nfunction createNumberField(\n name: string,\n errorMessages?: PayrollEditEmployeeErrorMessages,\n): PayrollEditEmployeeFieldComponent {\n return function BoundNumberField(props: PayrollEditEmployeeFieldProps) {\n // The field resolves its own validation copy from its bound path, so the\n // consumer supplies error copy once (keyed by code) and never reconstructs\n // form paths or guesses which rule a field can fail. name, type, min, and\n // errorMessage are applied after the spread so callers can't override the\n // binding or the non-negative numeric contract via custom props.\n const errorMessage = useFieldErrorMessage(\n name,\n errorMessages as ValidationMessages<PayrollEditEmployeeErrorCode> | undefined,\n )\n return (\n <TextInputField {...props} name={name} type=\"number\" min={0} errorMessage={errorMessage} />\n )\n }\n}\n\nfunction createPaymentMethodField(): PayrollEditEmployeePaymentMethodField {\n return function BoundPaymentMethodField(props: PayrollEditEmployeePaymentMethodFieldProps) {\n return (\n <RadioGroupHookField<never, PayrollUpdatePaymentMethod> {...props} name=\"paymentMethod\" />\n )\n }\n}\n\nfunction createTextField(name: string): ComponentType<ReimbursementDescriptionFieldProps> {\n return function BoundTextField(props: ReimbursementDescriptionFieldProps) {\n return <TextInputField {...props} name={name} />\n }\n}\n\n/**\n * Builds the draft \"add reimbursement\" field group, binding its Description and\n * Amount fields to the `reimbursementDraft` form path.\n *\n * @param errorMessages - Copy for each validation error code, baked into the amount field so it self-resolves.\n * @returns The pre-bound draft field group for `form.Fields.reimbursementDraft`.\n * @internal\n */\nexport function createReimbursementDraftFields(\n errorMessages?: PayrollEditEmployeeErrorMessages,\n): ReimbursementDraftFields {\n return {\n Description: createTextField('reimbursementDraft.description'),\n Amount: createNumberField('reimbursementDraft.amount', errorMessages),\n }\n}\n\n// ── Builders ───────────────────────────────────────────────────────────\n\n/** @internal */\nexport interface CreatePayrollEditEmployeeFieldsOptions {\n employeeCompensation: PayrollEmployeeCompensationsType | undefined\n /**\n * Fixed compensations to render, already merged with blank placeholders for\n * every company earning type (see `resolveEditableFixedCompensations`).\n */\n fixedCompensations: NonNullable<PayrollEmployeeCompensationsType['fixedCompensations']>\n workweeks: NormalizedWorkweek[]\n payrollCategory: PayrollCategory\n hasDirectDepositSetup: boolean\n /** Names of earning types included in the regular-rate-of-pay overtime calculation. */\n overtimeEarningNames: Set<string>\n /** Whether the employee is overtime-eligible (nonexempt family). Gates per-workweek splitting. */\n isOvertimeEligible: boolean\n /**\n * Gates per-workweek splitting\n * alongside `isOvertimeEligible`, and whether Overtime/Double-overtime rows\n * are included in `hours`.\n */\n withOvertime: boolean\n /** Job title lookup by job UUID, for per-job section headings. */\n jobTitlesByUuid: Map<string, string>\n /** Accrual balance by time-off policy name, for the remaining-balance display. */\n timeOffAccrualByName: Map<string, string>\n /** Copy for each validation error code, baked into every bound field so it self-resolves. */\n errorMessages?: PayrollEditEmployeeErrorMessages\n}\n\n/**\n * A time-off policy's remaining balance: its accrual balance minus the entered\n * hours. `null` when the policy has no tracked accrual balance (final-payout\n * rows). Shared by the field builder (seeding the initial value) and the hook\n * (recomputing it live as the user edits).\n *\n * @param accrualBalance - The policy's accrual balance, or `undefined` when untracked.\n * @param enteredHours - The currently entered hours for the policy.\n * @returns The remaining balance, or `null` when untracked.\n * @internal\n */\nexport function computeTimeOffRemaining(\n accrualBalance: string | undefined,\n enteredHours: string | null | undefined,\n): number | null {\n if (accrualBalance == null) return null\n return parseFloat(accrualBalance) - (parseFloat(enteredHours ?? '') || 0)\n}\n\nfunction buildBreakdownSection(\n compensations: Array<{ jobUuid?: string; name?: string }>,\n workweeks: NormalizedWorkweek[],\n pathPrefix: 'hours' | 'overtimeIncludedEarnings',\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n errorMessages: PayrollEditEmployeeErrorMessages | undefined,\n): HourEntry[] | Record<string, HourEntry[]> {\n const rows = compensations.filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n\n const toEntry = (\n row: { jobUuid: string; name: string },\n weekStart: string,\n includeWorkweek: boolean,\n ): HourEntry => ({\n key: includeWorkweek ? `${row.jobUuid}:${row.name}:${weekStart}` : `${row.jobUuid}:${row.name}`,\n jobUuid: row.jobUuid,\n name: row.name,\n ...(includeWorkweek ? { workweekStart: weekStart } : {}),\n Field: createNumberField(\n `${pathPrefix}.${row.jobUuid}.${row.name}.${weekStart}`,\n errorMessages,\n ),\n })\n\n // Split into per-workweek columns only for overtime-eligible employees while\n // `withOvertime` is on; workweek breakdowns exist solely to compute overtime\n // premiums, so an ineligible employee renders flat even on a multi-workweek\n // payroll, and an eligible one stays flat until `withOvertime` is set.\n if (workweeks.length > 1 && isOvertimeEligible && withOvertime) {\n const byWeek: Record<string, HourEntry[]> = {}\n for (const workweek of workweeks) {\n byWeek[workweek.startDate] = rows.map(row => toEntry(row, workweek.startDate, true))\n }\n return byWeek\n }\n\n const weekStart = workweeks[0]?.startDate ?? ''\n return rows.map(row => toEntry(row, weekStart, false))\n}\n\n/**\n * Builds the render-ready {@link PayrollEditEmployeeFields} from the prepared\n * compensation.\n *\n * @remarks\n * Hours and overtime-affecting earnings are grouped per job into `jobs` (a job\n * appears if it has hourly lines or overtime-affecting earnings). Fixed\n * compensations are split by whether their earning type is included in the\n * regular-rate-of-pay overtime calculation (`overtimeEarningNames`): included\n * earnings become each job's additional earnings, the rest become the flat,\n * employee-level `overtimeExcludedEarnings` section. Time off comes from the paid-time-off list,\n * final payout is added only for dismissal payrolls, and the payment-method\n * selector appears only when direct deposit is set up.\n *\n * @param options - The prepared compensation, normalized workweeks, payroll category, direct-deposit flag, overtime earning names, eligibility, the `withOvertime` flag, job titles, time-off accrual balances and entered values, and error copy.\n * @returns The populated field collections.\n * @internal\n */\nexport function createPayrollEditEmployeeFields({\n employeeCompensation,\n fixedCompensations,\n workweeks,\n payrollCategory,\n hasDirectDepositSetup,\n overtimeEarningNames,\n isOvertimeEligible,\n withOvertime,\n jobTitlesByUuid,\n timeOffAccrualByName,\n errorMessages,\n}: CreatePayrollEditEmployeeFieldsOptions): PayrollEditEmployeeFields {\n const hourlyCompensations = employeeCompensation?.hourlyCompensations ?? []\n const overtimeAffecting = fixedCompensations.filter(\n compensation => compensation.name != null && overtimeEarningNames.has(compensation.name),\n )\n const nonOvertime = fixedCompensations.filter(\n compensation => compensation.name == null || !overtimeEarningNames.has(compensation.name),\n )\n\n // A job appears if it has hourly lines or overtime-affecting earnings, in first\n // appearance order across those two sources.\n const jobUuids: string[] = []\n for (const compensation of [...hourlyCompensations, ...overtimeAffecting]) {\n if (compensation.jobUuid && !jobUuids.includes(compensation.jobUuid)) {\n jobUuids.push(compensation.jobUuid)\n }\n }\n\n const isOvertimeName = (name: string | null | undefined) =>\n name === COMPENSATION_NAME_OVERTIME || name === COMPENSATION_NAME_DOUBLE_OVERTIME\n\n const jobs: JobFields[] = jobUuids.map(jobUuid => {\n const jobHourlyCompensations = hourlyCompensations.filter(\n compensation => compensation.jobUuid === jobUuid,\n )\n // Overtime/Double-overtime rows stay out of `hours` entirely while\n // `withOvertime` is off — their underlying form values are untouched\n // (still whatever the prepared compensation carried), so hiding the row\n // can't lose or corrupt data. Driven by the single, employee-level flag —\n // no per-job hidden state.\n const visibleHourlyCompensations = withOvertime\n ? jobHourlyCompensations\n : jobHourlyCompensations.filter(compensation => !isOvertimeName(compensation.name))\n\n return {\n jobUuid,\n title: jobTitlesByUuid.get(jobUuid),\n hours: buildBreakdownSection(\n visibleHourlyCompensations,\n workweeks,\n 'hours',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n ),\n }\n })\n\n // Overtime-affecting earnings render as one employee-level section spanning\n // every job. Each entry keeps its per-job form path\n // (`overtimeIncludedEarnings.<jobUuid>.<name>`), so the flat section still binds and\n // submits per job.\n const overtimeIncludedEarnings = buildBreakdownSection(\n overtimeAffecting,\n workweeks,\n 'overtimeIncludedEarnings',\n isOvertimeEligible,\n withOvertime,\n errorMessages,\n )\n\n const overtimeExcludedEarnings: OtherEntry[] = nonOvertime\n .filter(\n (compensation): compensation is { jobUuid: string; name: string } =>\n Boolean(compensation.jobUuid) && Boolean(compensation.name),\n )\n .map(compensation => ({\n key: `${compensation.jobUuid}:${compensation.name}`,\n id: compensation.name,\n Field: createNumberField(\n `overtimeExcludedEarnings.${compensation.jobUuid}.${compensation.name}`,\n errorMessages,\n ),\n }))\n\n const timeOffRows = (employeeCompensation?.paidTimeOff ?? []).filter(entry => entry.name)\n const timeOff: TimeOffEntry[] = timeOffRows.map(entry => ({\n key: `timeOff:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`timeOff.${entry.name!}`, errorMessages),\n // Seeded from the initial entered hours; the hook recomputes it live.\n remaining: computeTimeOffRemaining(timeOffAccrualByName.get(entry.name!), entry.hours),\n }))\n\n // Final-payout rows never show a remaining balance.\n const finalPayout =\n payrollCategory === PayrollCategory.Dismissal\n ? timeOffRows.map(entry => ({\n key: `finalPayout:${entry.name!}`,\n name: entry.name!,\n Field: createNumberField(`finalPayout.${entry.name!}`, errorMessages),\n remaining: null,\n }))\n : undefined\n\n return {\n jobs,\n overtimeIncludedEarnings,\n overtimeExcludedEarnings,\n timeOff,\n finalPayout,\n paymentMethod: hasDirectDepositSetup ? createPaymentMethodField() : undefined,\n }\n}\n"],"names":["isSplitByWorkweek","section","createNumberField","name","errorMessages","props","errorMessage","useFieldErrorMessage","jsx","TextInputField","createPaymentMethodField","RadioGroupHookField","createTextField","createReimbursementDraftFields","computeTimeOffRemaining","accrualBalance","enteredHours","buildBreakdownSection","compensations","workweeks","pathPrefix","isOvertimeEligible","withOvertime","rows","compensation","toEntry","row","weekStart","includeWorkweek","byWeek","workweek","createPayrollEditEmployeeFields","employeeCompensation","fixedCompensations","payrollCategory","hasDirectDepositSetup","overtimeEarningNames","jobTitlesByUuid","timeOffAccrualByName","hourlyCompensations","overtimeAffecting","nonOvertime","jobUuids","isOvertimeName","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","jobs","jobUuid","jobHourlyCompensations","visibleHourlyCompensations","overtimeIncludedEarnings","overtimeExcludedEarnings","timeOffRows","entry","timeOff","finalPayout","PayrollCategory"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { PayrollUpdatePaymentMethod as p } from "@gusto/embedded-api/models/components/payrollupdate";
2
2
  import { RFCDate as S } from "@gusto/embedded-api/types/rfcdate";
3
- import { PayrollCategory as x, isOffCyclePayroll as R } from "../../../payrollTypes.js";
3
+ import { PayrollCategory as T, isOffCyclePayroll as R } from "../../../payrollTypes.js";
4
4
  import { cleanupReimbursements as _ } from "../../../helpers.js";
5
5
  import { SDKInternalError as F } from "../../../../../types/sdkError.js";
6
- import { COMPENSATION_NAME_OVERTIME as W, COMPENSATION_NAME_DOUBLE_OVERTIME as H, FlsaStatus as L, EXCLUDED_ADDITIONAL_EARNINGS as I } from "../../../../../shared/constants.js";
6
+ import { COMPENSATION_NAME_OVERTIME as W, COMPENSATION_NAME_DOUBLE_OVERTIME as H, FlsaStatus as L, EXCLUDED_ADDITIONAL_EARNINGS as y } from "../../../../../shared/constants.js";
7
7
  function Y(t, n) {
8
8
  const e = (t ?? []).flatMap(
9
9
  (o) => o.startDate && o.endDate ? [{ startDate: o.startDate.toString(), endDate: o.endDate.toString() }] : []
@@ -28,17 +28,17 @@ function J(t, n, e, o) {
28
28
  if (o !== L.OWNER && e)
29
29
  for (const i of n ?? []) {
30
30
  const a = i.name;
31
- if (!a || I.includes(a)) continue;
31
+ if (!a || y.includes(a)) continue;
32
32
  l.some((D) => D.name?.toLowerCase() === a.toLowerCase()) || l.push({ name: a, jobUuid: e });
33
33
  }
34
- return l.filter((i) => i.name && !I.includes(i.name)).sort((i, a) => (i.name ?? "").localeCompare(a.name ?? ""));
34
+ return l.filter((i) => i.name && !y.includes(i.name)).sort((i, a) => (i.name ?? "").localeCompare(a.name ?? ""));
35
35
  }
36
36
  function w(t) {
37
37
  return (t ?? []).some(
38
38
  (n) => (n.name === W || n.name === H) && parseFloat(n.hours ?? "0") > 0
39
39
  );
40
40
  }
41
- function A(t, n) {
41
+ function U(t, n) {
42
42
  return !t || t.length === 0 ? !1 : n.every(
43
43
  (e) => t.some(
44
44
  (o) => o.startDate?.toString() === e.startDate && o.endDate?.toString() === e.endDate
@@ -47,7 +47,7 @@ function A(t, n) {
47
47
  }
48
48
  function k(t, n) {
49
49
  return (t ?? []).some(
50
- (e) => A(e.breakdowns, n)
50
+ (e) => U(e.breakdowns, n)
51
51
  );
52
52
  }
53
53
  function b(t) {
@@ -59,12 +59,12 @@ function N(t) {
59
59
  const n = b(t);
60
60
  return n === "0" ? "" : n;
61
61
  }
62
- function j(t, n, e, o) {
62
+ function v(t, n, e, o) {
63
63
  const l = t[0]?.startDate ?? "";
64
64
  if (!o)
65
65
  return { [l]: N(n) };
66
66
  const i = {};
67
- return A(e, t) ? t.forEach((a) => {
67
+ return U(e, t) ? t.forEach((a) => {
68
68
  const u = e?.find(
69
69
  (D) => D.startDate?.toString() === a.startDate
70
70
  );
@@ -78,7 +78,7 @@ function tt(t, n, e, o, l, i, a = t?.fixedCompensations ?? []) {
78
78
  for (const r of t?.hourlyCompensations ?? []) {
79
79
  if (!r.jobUuid || !r.name) continue;
80
80
  const h = D[r.jobUuid] ??= {};
81
- h[r.name] = j(
81
+ h[r.name] = v(
82
82
  n,
83
83
  r.hours,
84
84
  r.breakdowns,
@@ -90,7 +90,7 @@ function tt(t, n, e, o, l, i, a = t?.fixedCompensations ?? []) {
90
90
  if (!(!r.jobUuid || !r.name))
91
91
  if (o.has(r.name)) {
92
92
  const h = E[r.jobUuid] ??= {};
93
- h[r.name] = j(
93
+ h[r.name] = v(
94
94
  n,
95
95
  r.amount,
96
96
  r.breakdowns,
@@ -103,7 +103,7 @@ function tt(t, n, e, o, l, i, a = t?.fixedCompensations ?? []) {
103
103
  const O = {}, M = {};
104
104
  for (const r of t?.paidTimeOff ?? [])
105
105
  r.name && (O[r.name] = b(r.hours), M[r.name] = b(r.finalPayoutUnusedHoursInput));
106
- const y = (t?.reimbursements ?? []).map((r) => ({
106
+ const I = (t?.reimbursements ?? []).map((r) => ({
107
107
  uuid: r.uuid ?? null,
108
108
  description: r.description ?? "",
109
109
  amount: r.amount,
@@ -111,11 +111,11 @@ function tt(t, n, e, o, l, i, a = t?.fixedCompensations ?? []) {
111
111
  }));
112
112
  return {
113
113
  hours: D,
114
- additionalEarnings: E,
115
- other: g,
114
+ overtimeIncludedEarnings: E,
115
+ overtimeExcludedEarnings: g,
116
116
  timeOff: O,
117
117
  finalPayout: M,
118
- reimbursements: y,
118
+ reimbursements: I,
119
119
  reimbursementDraft: { description: "", amount: "" },
120
120
  paymentMethod: $(t?.paymentMethod, e)
121
121
  };
@@ -123,14 +123,14 @@ function tt(t, n, e, o, l, i, a = t?.fixedCompensations ?? []) {
123
123
  function $(t, n) {
124
124
  return t === p.Check ? p.Check : t === p.DirectDeposit && n ? p.DirectDeposit : n ? p.DirectDeposit : p.Check;
125
125
  }
126
- function P(t, n) {
126
+ function j(t, n) {
127
127
  const e = /* @__PURE__ */ new Map();
128
128
  for (const o of t ?? [])
129
129
  !o.jobUuid || !o.name || e.set(`${o.jobUuid}|${o.name}`, n(o) ?? "");
130
130
  return e;
131
131
  }
132
132
  const V = 2, z = 6;
133
- function U(t, n, e) {
133
+ function P(t, n, e) {
134
134
  const o = 10 ** e, l = n.reduce((i, a) => {
135
135
  const u = parseFloat(t[a.startDate] ?? "0") || 0;
136
136
  return i + Math.round(u * o);
@@ -138,10 +138,10 @@ function U(t, n, e) {
138
138
  return String(l / o);
139
139
  }
140
140
  function nt(t, n, e, o, l, i) {
141
- const a = e.length > 1 && l && i, u = (s) => s != null && s !== "", D = P(
141
+ const a = e.length > 1 && l && i, u = (s) => s != null && s !== "", D = j(
142
142
  n?.hourlyCompensations,
143
143
  (s) => s.hours
144
- ), E = P(
144
+ ), E = j(
145
145
  n?.fixedCompensations,
146
146
  (s) => s.amount
147
147
  ), g = (s) => e.every((m) => u(s[m.startDate])), O = (s, m, f, c) => {
@@ -152,7 +152,7 @@ function nt(t, n, e, o, l, i) {
152
152
  {
153
153
  jobUuid: s,
154
154
  name: f,
155
- hours: U(c, e, z),
155
+ hours: P(c, e, z),
156
156
  breakdowns: e.map((d) => ({
157
157
  startDate: new S(d.startDate),
158
158
  endDate: new S(d.endDate),
@@ -160,12 +160,12 @@ function nt(t, n, e, o, l, i) {
160
160
  }))
161
161
  }
162
162
  ] : [] : [{ jobUuid: s, name: f, hours: O(s, f, c, D) }])
163
- ), y = Object.entries(t.additionalEarnings).flatMap(
163
+ ), I = Object.entries(t.overtimeIncludedEarnings).flatMap(
164
164
  ([s, m]) => Object.entries(m).flatMap(([f, c]) => a ? g(c) ? [
165
165
  {
166
166
  jobUuid: s,
167
167
  name: f,
168
- amount: U(c, e, V),
168
+ amount: P(c, e, V),
169
169
  breakdowns: e.map((d) => ({
170
170
  startDate: new S(d.startDate),
171
171
  endDate: new S(d.endDate),
@@ -175,17 +175,17 @@ function nt(t, n, e, o, l, i) {
175
175
  ] : [] : [
176
176
  { jobUuid: s, name: f, amount: O(s, f, c, E) }
177
177
  ])
178
- ), r = Object.entries(t.other).flatMap(
178
+ ), r = Object.entries(t.overtimeExcludedEarnings).flatMap(
179
179
  ([s, m]) => Object.entries(m).map(([f, c]) => ({
180
180
  jobUuid: s,
181
181
  name: f,
182
182
  amount: u(c) ? c : E.get(`${s}|${f}`) ?? "0"
183
183
  }))
184
- ), h = [...y, ...r], C = o === x.Dismissal, T = Object.entries(t.timeOff).map(([s, m]) => ({
184
+ ), h = [...I, ...r], x = o === T.Dismissal, A = Object.entries(t.timeOff).map(([s, m]) => ({
185
185
  name: s,
186
186
  hours: m || "0",
187
- ...C && t.finalPayout[s] != null ? { finalPayoutUnusedHoursInput: t.finalPayout[s] || "0" } : {}
188
- })), v = !R(o);
187
+ ...x && t.finalPayout[s] != null ? { finalPayoutUnusedHoursInput: t.finalPayout[s] || "0" } : {}
188
+ })), C = !R(o);
189
189
  return {
190
190
  employeeUuid: n?.employeeUuid,
191
191
  version: n?.version,
@@ -194,8 +194,8 @@ function nt(t, n, e, o, l, i) {
194
194
  ...t.paymentMethod ? { paymentMethod: t.paymentMethod } : {},
195
195
  hourlyCompensations: M,
196
196
  fixedCompensations: h,
197
- paidTimeOff: T,
198
- ...v ? { reimbursements: _(t.reimbursements) } : {}
197
+ paidTimeOff: A,
198
+ ...C ? { reimbursements: _(t.reimbursements) } : {}
199
199
  };
200
200
  }
201
201
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"payrollEditEmployeeHelpers.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeHelpers.ts"],"sourcesContent":["import type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { EarningTypeList } from '@gusto/embedded-api/models/components/earningtypelist'\nimport {\n PayrollUpdatePaymentMethod,\n type PayrollUpdateEmployeeCompensations,\n} from '@gusto/embedded-api/models/components/payrollupdate'\nimport { RFCDate } from '@gusto/embedded-api/types/rfcdate'\nimport type {\n PayrollEditEmployeeFormData,\n PayrollEditEmployeeFormOutputs,\n} from './payrollEditEmployeeSchema'\nimport { PayrollCategory, isOffCyclePayroll } from '@/components/Payroll/payrollTypes'\nimport { cleanupReimbursements } from '@/components/Payroll/helpers'\nimport { SDKInternalError } from '@/types/sdkError'\nimport {\n COMPENSATION_NAME_DOUBLE_OVERTIME,\n COMPENSATION_NAME_OVERTIME,\n EXCLUDED_ADDITIONAL_EARNINGS,\n FlsaStatus,\n} from '@/shared/constants'\n\n/** One fixed-compensation line off the prepared compensation. */\ntype FixedCompensationEntry = NonNullable<\n PayrollEmployeeCompensationsType['fixedCompensations']\n>[number]\n\n/**\n * Normalized form of a workweek: the API exposes\n * `{ startDate?: RFCDate; endDate?: RFCDate }`, but the hook keys week-maps by\n * `YYYY-MM-DD` strings and builds breakdowns from them, so both boundaries are\n * required strings here. Surfaced on the hook's `data.workweeks` so the UI can\n * label each per-workweek column without re-parsing the raw API workweeks.\n *\n * @internal\n */\nexport interface NormalizedWorkweek {\n startDate: string\n endDate: string\n}\n\n/**\n * Normalizes the prepared payroll's top-level `workweeks` into\n * {@link NormalizedWorkweek} boundary strings, falling back to a single\n * pay-period-spanning workweek when the API returns no workweek boundaries.\n *\n * @param workweeks - The prepared payroll's top-level `workweeks` (RFCDate boundaries), possibly `null`.\n * @param payPeriod - The prepared payroll's `payPeriod`, used as the single-workweek fallback.\n * @returns One entry per workweek; a single entry spanning the pay period when none are supplied.\n * @throws SDKInternalError when neither workweeks nor a pay period are present (a malformed prepared payroll).\n * @internal\n */\nexport function normalizeWorkweeks(\n workweeks: Array<{ startDate?: RFCDate; endDate?: RFCDate }> | null | undefined,\n payPeriod: { startDate?: string; endDate?: string } | undefined,\n): NormalizedWorkweek[] {\n const normalized = (workweeks ?? []).flatMap(week =>\n week.startDate && week.endDate\n ? [{ startDate: week.startDate.toString(), endDate: week.endDate.toString() }]\n : [],\n )\n\n if (normalized.length > 0) {\n return normalized\n }\n\n if (payPeriod?.startDate && payPeriod.endDate) {\n return [{ startDate: payPeriod.startDate, endDate: payPeriod.endDate }]\n }\n\n // A prepared payroll always carries a pay period, so reaching here means the\n // response was malformed. Fail loud rather than build an empty, mis-keyed form\n // that could submit an employee's pay against a blank workweek.\n throw new SDKInternalError('Prepared payroll has no workweeks or pay period to derive from')\n}\n\n/**\n * Collects the names of earning types included in the regular-rate-of-pay\n * overtime calculation. These earnings render in the workweek-breakdown\n * additional-earnings section; all others fall into the flat `other` section.\n *\n * @param earningTypeList - The company's default and custom earning types.\n * @returns A set of earning-type names with `includedInOvertimePay` set.\n * @internal\n */\nexport function collectOvertimeEarningNames(\n earningTypeList: EarningTypeList | undefined,\n): Set<string> {\n const names = new Set<string>()\n for (const earningType of [\n ...(earningTypeList?.default ?? []),\n ...(earningTypeList?.custom ?? []),\n ]) {\n if (earningType.name && earningType.includedInOvertimePay) {\n names.add(earningType.name)\n }\n }\n return names\n}\n\n/**\n * Merges the employee's existing fixed compensations with a blank placeholder for\n * every payroll fixed-compensation type they don't yet have, mirroring the stable editor\n * (`getAdditionalEarningsCompensations`). This is what lets the editor surface an\n * empty input for Bonus, Commission, etc. even when the prepared payroll carries\n * no fixed compensations. Placeholders attach to the primary job and carry no\n * amount (blank), so an untouched earning submits as zero without altering pay.\n *\n * @remarks\n * Owners (FLSA status `Owner`) never receive placeholders. Earning types that are\n * handled elsewhere or never shown as additional earnings\n * ({@link EXCLUDED_ADDITIONAL_EARNINGS}) and inactive types are skipped. The\n * result is sorted alphabetically by name. The regular-rate-of-pay split between\n * additional earnings and `other` happens downstream via `overtimeEarningNames`;\n * this helper only decides which earning lines exist.\n *\n * @param existingFixedCompensations - The prepared compensation's fixed compensations.\n * @param fixedCompensationTypes - The prepared payroll's `fixedCompensationTypes` (the same source the stable editor uses).\n * @param primaryJobUuid - The employee's primary job UUID; placeholders attach here.\n * @param flsaStatus - The employee's FLSA status; owners get no placeholders.\n * @returns The merged, filtered, alphabetically sorted fixed-compensation lines.\n * @internal\n */\nexport function resolveEditableFixedCompensations(\n existingFixedCompensations: FixedCompensationEntry[] | undefined,\n fixedCompensationTypes: Array<{ name?: string | null }> | undefined,\n primaryJobUuid: string | undefined,\n flsaStatus: string | undefined,\n): FixedCompensationEntry[] {\n const merged: FixedCompensationEntry[] = [...(existingFixedCompensations ?? [])]\n\n if (flsaStatus !== FlsaStatus.OWNER && primaryJobUuid) {\n for (const compensationType of fixedCompensationTypes ?? []) {\n const name = compensationType.name\n if (!name) continue\n if (EXCLUDED_ADDITIONAL_EARNINGS.includes(name)) continue\n const exists = merged.some(entry => entry.name?.toLowerCase() === name.toLowerCase())\n if (!exists) merged.push({ name, jobUuid: primaryJobUuid })\n }\n }\n\n return merged\n .filter(entry => entry.name && !EXCLUDED_ADDITIONAL_EARNINGS.includes(entry.name))\n .sort((a, b) => (a.name ?? '').localeCompare(b.name ?? ''))\n}\n\n/**\n * Whether the employee's prepared compensation already carries non-zero\n * Overtime or Double-overtime hours.\n *\n * @remarks\n * Used to default the single `withOvertime` flag: an employee who already\n * has real overtime hours starts with the workweek split shown rather than\n * requiring an extra click to see data that's already there.\n *\n * @param hourlyCompensations - The prepared compensation's hourly lines.\n * @returns `true` when any Overtime or Double-overtime line has hours greater than zero.\n * @internal\n */\nexport function hasExistingOvertimeHours(\n hourlyCompensations: PayrollEmployeeCompensationsType['hourlyCompensations'] | undefined,\n): boolean {\n return (hourlyCompensations ?? []).some(\n compensation =>\n (compensation.name === COMPENSATION_NAME_OVERTIME ||\n compensation.name === COMPENSATION_NAME_DOUBLE_OVERTIME) &&\n parseFloat(compensation.hours ?? '0') > 0,\n )\n}\n\n/**\n * Whether a line's `breakdowns` exactly cover every workweek in `workweeks`\n * (each workweek has a breakdown entry matching both its start and end date).\n */\nfunction lineBreakdownsMatchWorkweeks(\n breakdowns: Array<{ startDate?: RFCDate; endDate?: RFCDate }> | undefined,\n workweeks: NormalizedWorkweek[],\n): boolean {\n if (!breakdowns || breakdowns.length === 0) return false\n return workweeks.every(workweek =>\n breakdowns.some(\n breakdown =>\n breakdown.startDate?.toString() === workweek.startDate &&\n breakdown.endDate?.toString() === workweek.endDate,\n ),\n )\n}\n\n/**\n * Whether any of the employee's hourly-compensation lines already carries a\n * real, per-workweek `breakdowns` array that exactly tiles the current pay\n * period's workweeks.\n *\n * @remarks\n * Used alongside {@link hasExistingOvertimeHours} to default the single\n * `withOvertime` flag: an employee whose hours are already broken down by\n * workweek (e.g. a previous edit entered real per-week values) starts with the\n * workweek split shown, seeded from those breakdowns rather than from a blank\n * or first-cell-only guess. See {@link buildWeekMap}, which applies the same\n * per-line check to decide each line's population mode.\n *\n * @param hourlyCompensations - The prepared compensation's hourly lines.\n * @param workweeks - Normalized workweeks for the pay period.\n * @returns `true` when at least one hourly line's breakdowns cover every workweek.\n * @internal\n */\nexport function hasBreakdownsMatchingWorkweeks(\n hourlyCompensations: PayrollEmployeeCompensationsType['hourlyCompensations'] | undefined,\n workweeks: NormalizedWorkweek[],\n): boolean {\n return (hourlyCompensations ?? []).some(compensation =>\n lineBreakdownsMatchWorkweeks(compensation.breakdowns, workweeks),\n )\n}\n\n/**\n * Trims an API decimal string (e.g. `\"40.000\"`, `\"500.00\"`) to a clean editable\n * value (`\"40\"`, `\"500\"`), preserving real fractional parts (`\"40.5\"`). A blank\n * or non-numeric value returns `''` (meaning \"not provided\").\n */\nfunction formatAmountInput(value: string | null | undefined): string {\n if (value == null || value === '') return ''\n const parsed = parseFloat(value)\n return Number.isNaN(parsed) ? '' : parsed.toString()\n}\n\n/**\n * Seeds a cell from a line's total: same as {@link formatAmountInput} except a\n * zero total yields `''` rather than `\"0\"`. A line whose total is zero (e.g. an\n * Overtime line with no overtime) should render as a blank cell the user can\n * fill in, not a pre-filled `0` — and a pre-filled `0` would also count as a\n * filled cell, tripping the per-row \"fill every workweek\" check for a line the\n * user never actually touched. Only used for total-seeded cells, never for real\n * per-week breakdown values (a genuine `0` breakdown must survive to keep a\n * matched split's tiling intact).\n */\nfunction formatSeededTotal(value: string | null | undefined): string {\n const formatted = formatAmountInput(value)\n return formatted === '0' ? '' : formatted\n}\n\n/**\n * Builds one job+name line's week map in one of three shapes, gated by\n * `isSplit` (`workweeks.length > 1 && isOvertimeEligible && withOvertime`):\n *\n * - Collapsed (`isSplit` false): a single key — the first workweek's start —\n * holding the total. No key is emitted for any other workweek, which is what\n * keeps a collapsed row's per-row validation a no-op (see\n * {@link createPayrollEditEmployeeSchema}).\n * - Split, breakdowns match ({@link hasBreakdownsMatchingWorkweeks} true for\n * this line): one key per workweek, each seeded from its real breakdown value.\n * - Split, no matching breakdowns: one key per workweek, with only the first\n * seeded (from the total) and the rest left blank — never auto-distributed,\n * so the user must fill them in (enforced by the schema's per-row check).\n */\nfunction buildWeekMap(\n workweeks: NormalizedWorkweek[],\n total: string | undefined,\n breakdowns:\n Array<{ startDate?: RFCDate; endDate?: RFCDate; hours?: string; amount?: string }> | undefined,\n isSplit: boolean,\n): Record<string, string> {\n const firstWorkweekStart = workweeks[0]?.startDate ?? ''\n\n if (!isSplit) {\n return { [firstWorkweekStart]: formatSeededTotal(total) }\n }\n\n const weekMap: Record<string, string> = {}\n if (lineBreakdownsMatchWorkweeks(breakdowns, workweeks)) {\n workweeks.forEach(workweek => {\n const breakdown = breakdowns?.find(\n entry => entry.startDate?.toString() === workweek.startDate,\n )\n weekMap[workweek.startDate] = formatAmountInput(breakdown?.hours ?? breakdown?.amount)\n })\n } else {\n workweeks.forEach((workweek, index) => {\n weekMap[workweek.startDate] = index === 0 ? formatSeededTotal(total) : ''\n })\n }\n return weekMap\n}\n\n/**\n * Derives the form's default values from the employee's prepared compensation.\n *\n * @remarks\n * Hourly and additional earnings are expanded into per-workweek maps via\n * {@link buildWeekMap}: collapsed to the total when not split, seeded from real\n * breakdowns or first-cell-only otherwise. Time off, final payout,\n * reimbursements, and payment method are read straight off the compensation.\n *\n * @param employeeCompensation - The employee's prepared compensation, if loaded.\n * @param workweeks - Normalized workweeks for the pay period.\n * @param withOvertime - The single, form-wide overtime-mode flag (see {@link hasExistingOvertimeHours}, {@link hasBreakdownsMatchingWorkweeks}, `actions.addOvertime`). Gates splitting alongside `isOvertimeEligible`.\n * @returns Default {@link PayrollEditEmployeeFormData} for `useForm`.\n * @internal\n */\nexport function derivePayrollEditEmployeeDefaults(\n employeeCompensation: PayrollEmployeeCompensationsType | undefined,\n workweeks: NormalizedWorkweek[],\n hasDirectDepositSetup: boolean,\n overtimeEarningNames: Set<string>,\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n fixedCompensations: FixedCompensationEntry[] = employeeCompensation?.fixedCompensations ?? [],\n): PayrollEditEmployeeFormData {\n // Only overtime-eligible employees split hours/earnings by workweek, and only\n // while the single `withOvertime` flag is on; everyone else renders (and\n // seeds) flat, even on a multi-workweek payroll.\n const isSplit = workweeks.length > 1 && isOvertimeEligible && withOvertime\n\n const hours: PayrollEditEmployeeFormData['hours'] = {}\n for (const compensation of employeeCompensation?.hourlyCompensations ?? []) {\n if (!compensation.jobUuid || !compensation.name) continue\n const jobHours = (hours[compensation.jobUuid] ??= {})\n jobHours[compensation.name] = buildWeekMap(\n workweeks,\n compensation.hours,\n compensation.breakdowns,\n isSplit,\n )\n }\n\n // Earnings whose earning type is included in the regular-rate-of-pay overtime\n // calculation stay workweek-breakdown; the rest are flat and land in `other`.\n // The hook owns this bucketing so the UI just renders each section.\n const additionalEarnings: PayrollEditEmployeeFormData['additionalEarnings'] = {}\n const other: PayrollEditEmployeeFormData['other'] = {}\n for (const compensation of fixedCompensations) {\n if (!compensation.jobUuid || !compensation.name) continue\n if (overtimeEarningNames.has(compensation.name)) {\n const jobEarnings = (additionalEarnings[compensation.jobUuid] ??= {})\n jobEarnings[compensation.name] = buildWeekMap(\n workweeks,\n compensation.amount,\n compensation.breakdowns,\n isSplit,\n )\n } else {\n const jobOther = (other[compensation.jobUuid] ??= {})\n jobOther[compensation.name] = formatAmountInput(compensation.amount)\n }\n }\n\n const timeOff: PayrollEditEmployeeFormData['timeOff'] = {}\n const finalPayout: PayrollEditEmployeeFormData['finalPayout'] = {}\n for (const entry of employeeCompensation?.paidTimeOff ?? []) {\n if (!entry.name) continue\n timeOff[entry.name] = formatAmountInput(entry.hours)\n finalPayout[entry.name] = formatAmountInput(entry.finalPayoutUnusedHoursInput)\n }\n\n const reimbursements: PayrollEditEmployeeFormData['reimbursements'] = (\n employeeCompensation?.reimbursements ?? []\n ).map(reimbursement => ({\n uuid: reimbursement.uuid ?? null,\n description: reimbursement.description ?? '',\n amount: reimbursement.amount,\n recurring: reimbursement.recurring ?? false,\n }))\n\n return {\n hours,\n additionalEarnings,\n other,\n timeOff,\n finalPayout,\n reimbursements,\n reimbursementDraft: { description: '', amount: '' },\n paymentMethod: resolvePaymentMethod(employeeCompensation?.paymentMethod, hasDirectDepositSetup),\n }\n}\n\n/**\n * Resolves the default payment method, mirroring the stable component (#2683):\n * an employee with no direct deposit set up defaults to (and is forced to)\n * `Check`, even when the prepared payroll carried `Direct Deposit` or nothing.\n * `Historical` is treated as unset. The result is always `Direct Deposit` or\n * `Check` — never `Historical` — since those are the only values the update\n * endpoint accepts.\n */\nfunction resolvePaymentMethod(\n paymentMethod: string | null | undefined,\n hasDirectDepositSetup: boolean,\n): PayrollUpdatePaymentMethod {\n if (paymentMethod === PayrollUpdatePaymentMethod.Check) return PayrollUpdatePaymentMethod.Check\n if (paymentMethod === PayrollUpdatePaymentMethod.DirectDeposit && hasDirectDepositSetup) {\n return PayrollUpdatePaymentMethod.DirectDeposit\n }\n return hasDirectDepositSetup\n ? PayrollUpdatePaymentMethod.DirectDeposit\n : PayrollUpdatePaymentMethod.Check\n}\n\nfunction originalTotals<T extends { jobUuid?: string; name?: string }>(\n compensations: T[] | undefined,\n selectTotal: (compensation: T) => string | null | undefined,\n): Map<string, string> {\n const totals = new Map<string, string>()\n for (const compensation of compensations ?? []) {\n if (!compensation.jobUuid || !compensation.name) continue\n totals.set(`${compensation.jobUuid}|${compensation.name}`, selectTotal(compensation) ?? '')\n }\n return totals\n}\n\n// Precision of the per-workweek values being summed: dollar amounts carry cents,\n// hours up to six places.\nconst AMOUNT_DECIMALS = 2\nconst HOURS_DECIMALS = 6\n\n/**\n * Sums per-workweek input values in integer minor units, then scales back.\n *\n * @remarks\n * Each value is already bounded to `decimals` places, so scaling it to an\n * integer (cents for amounts, millionths for hours) and summing those integers\n * is exact. Float-accumulating the decimals directly and rounding at the end\n * would instead leak binary error into the wire value (e.g. `0.1 + 0.2` →\n * `\"0.30000000000000004\"`), which the payroll API should never receive.\n */\nfunction sumWeekValues(\n weekMap: Record<string, string>,\n workweeks: NormalizedWorkweek[],\n decimals: number,\n): string {\n const factor = 10 ** decimals\n const totalMinorUnits = workweeks.reduce((total, workweek) => {\n const value = parseFloat(weekMap[workweek.startDate] ?? '0') || 0\n return total + Math.round(value * factor)\n }, 0)\n return String(totalMinorUnits / factor)\n}\n\n/**\n * Builds the `PayrollUpdate` employee-compensation payload from form values.\n *\n * @remarks\n * When the pay period spans a single workweek (or the employee isn't split by\n * workweek), totals are sent without `breakdowns`. When split, each hourly and\n * additional-earning line is decided independently — per line, not per job\n * (the API models breakdowns on each compensation line, not as a per-job\n * all-or-nothing unit):\n *\n * - A fully-filled line (every workweek cell has a value) sends `breakdowns`\n * tiling every workweek exactly, with the total equal to the sum of the\n * per-week values.\n * - An entirely blank line sends nothing for it — no `breakdowns`, no\n * fabricated `0`, no fabricated total — leaving it as the flat, untouched\n * value it already was.\n * - A partial line (some but not all cells filled) can never reach this\n * function: {@link createPayrollEditEmployeeSchema}'s per-row check blocks\n * submit until every cell in a touched row is filled.\n *\n * @param formData - Current parsed form values.\n * @param employeeCompensation - The prepared compensation, for identifying metadata (`version`, `employeeUuid`).\n * @param workweeks - Normalized workweeks for the pay period.\n * @param payrollCategory - The payroll category, gating itemized vs. off-cycle reimbursements.\n * @param isOvertimeEligible - Whether the employee is overtime-eligible (nonexempt family).\n * @param withOvertime - The single, form-wide overtime-mode flag. Gates splitting alongside `isOvertimeEligible` and `workweeks.length > 1`; when `false`, every line submits its flat (collapsed) value regardless of eligibility.\n * @returns The employee-compensation entry for the `PayrollUpdate` request body.\n * @internal\n */\nexport function buildPayrollUpdateEmployeeCompensation(\n formData: PayrollEditEmployeeFormOutputs,\n employeeCompensation: PayrollEmployeeCompensationsType | undefined,\n workweeks: NormalizedWorkweek[],\n payrollCategory: PayrollCategory,\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n): PayrollUpdateEmployeeCompensations {\n // Breakdowns are emitted only when the line is actually split by workweek:\n // multiple workweeks, an overtime-eligible employee, and `withOvertime` on.\n // This must match the field builder's gate so what renders and what submits\n // never drift.\n const isSplit = workweeks.length > 1 && isOvertimeEligible && withOvertime\n const hasValue = (value: string | undefined) => value != null && value !== ''\n const originalHours = originalTotals(\n employeeCompensation?.hourlyCompensations,\n comp => comp.hours,\n )\n const originalAmounts = originalTotals(\n employeeCompensation?.fixedCompensations,\n comp => comp.amount,\n )\n const isRowFilled = (weekMap: Record<string, string>) =>\n workweeks.every(workweek => hasValue(weekMap[workweek.startDate]))\n const collapsedValue = (\n jobUuid: string,\n name: string,\n weekMap: Record<string, string>,\n originals: Map<string, string>,\n ) => {\n const single = weekMap[workweeks[0]?.startDate ?? '']\n return hasValue(single) ? single! : (originals.get(`${jobUuid}|${name}`) ?? '0')\n }\n\n const hourlyCompensations = Object.entries(formData.hours).flatMap(([jobUuid, names]) =>\n Object.entries(names).flatMap(([name, weekMap]) => {\n if (!isSplit) {\n return [{ jobUuid, name, hours: collapsedValue(jobUuid, name, weekMap, originalHours) }]\n }\n if (!isRowFilled(weekMap)) return []\n return [\n {\n jobUuid,\n name,\n hours: sumWeekValues(weekMap, workweeks, HOURS_DECIMALS),\n breakdowns: workweeks.map(workweek => ({\n startDate: new RFCDate(workweek.startDate),\n endDate: new RFCDate(workweek.endDate),\n hours: weekMap[workweek.startDate]!,\n })),\n },\n ]\n }),\n )\n\n const breakdownEarnings = Object.entries(formData.additionalEarnings).flatMap(\n ([jobUuid, names]) =>\n Object.entries(names).flatMap(([name, weekMap]) => {\n if (!isSplit) {\n return [\n { jobUuid, name, amount: collapsedValue(jobUuid, name, weekMap, originalAmounts) },\n ]\n }\n if (!isRowFilled(weekMap)) return []\n return [\n {\n jobUuid,\n name,\n amount: sumWeekValues(weekMap, workweeks, AMOUNT_DECIMALS),\n breakdowns: workweeks.map(workweek => ({\n startDate: new RFCDate(workweek.startDate),\n endDate: new RFCDate(workweek.endDate),\n amount: weekMap[workweek.startDate]!,\n })),\n },\n ]\n }),\n )\n\n // Non-overtime earnings never carry breakdowns; they are sent as flat totals.\n const flatEarnings = Object.entries(formData.other).flatMap(([jobUuid, names]) =>\n Object.entries(names).map(([name, amount]) => ({\n jobUuid,\n name,\n amount: hasValue(amount) ? amount : (originalAmounts.get(`${jobUuid}|${name}`) ?? '0'),\n })),\n )\n\n const fixedCompensations = [...breakdownEarnings, ...flatEarnings]\n\n const isDismissal = payrollCategory === PayrollCategory.Dismissal\n const paidTimeOff = Object.entries(formData.timeOff).map(([name, value]) => ({\n name,\n hours: value || '0',\n ...(isDismissal && formData.finalPayout[name] != null\n ? { finalPayoutUnusedHoursInput: formData.finalPayout[name] || '0' }\n : {}),\n }))\n\n const usesItemizedReimbursements = !isOffCyclePayroll(payrollCategory)\n\n return {\n employeeUuid: employeeCompensation?.employeeUuid,\n version: employeeCompensation?.version as string | undefined,\n excluded: employeeCompensation?.excluded,\n memo: employeeCompensation?.memo || undefined,\n ...(formData.paymentMethod ? { paymentMethod: formData.paymentMethod } : {}),\n hourlyCompensations,\n fixedCompensations,\n paidTimeOff,\n ...(usesItemizedReimbursements\n ? { reimbursements: cleanupReimbursements(formData.reimbursements) }\n : {}),\n }\n}\n"],"names":["normalizeWorkweeks","workweeks","payPeriod","normalized","week","SDKInternalError","collectOvertimeEarningNames","earningTypeList","names","earningType","resolveEditableFixedCompensations","existingFixedCompensations","fixedCompensationTypes","primaryJobUuid","flsaStatus","merged","FlsaStatus","compensationType","name","EXCLUDED_ADDITIONAL_EARNINGS","entry","a","b","hasExistingOvertimeHours","hourlyCompensations","compensation","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","lineBreakdownsMatchWorkweeks","breakdowns","breakdown","workweek","hasBreakdownsMatchingWorkweeks","formatAmountInput","value","parsed","formatSeededTotal","formatted","buildWeekMap","total","isSplit","firstWorkweekStart","weekMap","index","derivePayrollEditEmployeeDefaults","employeeCompensation","hasDirectDepositSetup","overtimeEarningNames","isOvertimeEligible","withOvertime","fixedCompensations","hours","jobHours","additionalEarnings","other","jobEarnings","jobOther","timeOff","finalPayout","reimbursements","reimbursement","resolvePaymentMethod","paymentMethod","PayrollUpdatePaymentMethod","originalTotals","compensations","selectTotal","totals","AMOUNT_DECIMALS","HOURS_DECIMALS","sumWeekValues","decimals","factor","totalMinorUnits","buildPayrollUpdateEmployeeCompensation","formData","payrollCategory","hasValue","originalHours","comp","originalAmounts","isRowFilled","collapsedValue","jobUuid","originals","single","RFCDate","breakdownEarnings","flatEarnings","amount","isDismissal","PayrollCategory","paidTimeOff","usesItemizedReimbursements","isOffCyclePayroll","cleanupReimbursements"],"mappings":"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"}
1
+ {"version":3,"file":"payrollEditEmployeeHelpers.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeHelpers.ts"],"sourcesContent":["import type { PayrollEmployeeCompensationsType } from '@gusto/embedded-api/models/components/payrollemployeecompensationstype'\nimport type { EarningTypeList } from '@gusto/embedded-api/models/components/earningtypelist'\nimport {\n PayrollUpdatePaymentMethod,\n type PayrollUpdateEmployeeCompensations,\n} from '@gusto/embedded-api/models/components/payrollupdate'\nimport { RFCDate } from '@gusto/embedded-api/types/rfcdate'\nimport type {\n PayrollEditEmployeeFormData,\n PayrollEditEmployeeFormOutputs,\n} from './payrollEditEmployeeSchema'\nimport { PayrollCategory, isOffCyclePayroll } from '@/components/Payroll/payrollTypes'\nimport { cleanupReimbursements } from '@/components/Payroll/helpers'\nimport { SDKInternalError } from '@/types/sdkError'\nimport {\n COMPENSATION_NAME_DOUBLE_OVERTIME,\n COMPENSATION_NAME_OVERTIME,\n EXCLUDED_ADDITIONAL_EARNINGS,\n FlsaStatus,\n} from '@/shared/constants'\n\n/** One fixed-compensation line off the prepared compensation. */\ntype FixedCompensationEntry = NonNullable<\n PayrollEmployeeCompensationsType['fixedCompensations']\n>[number]\n\n/**\n * Normalized form of a workweek: the API exposes\n * `{ startDate?: RFCDate; endDate?: RFCDate }`, but the hook keys week-maps by\n * `YYYY-MM-DD` strings and builds breakdowns from them, so both boundaries are\n * required strings here. Surfaced on the hook's `data.workweeks` so the UI can\n * label each per-workweek column without re-parsing the raw API workweeks.\n *\n * @internal\n */\nexport interface NormalizedWorkweek {\n startDate: string\n endDate: string\n}\n\n/**\n * Normalizes the prepared payroll's top-level `workweeks` into\n * {@link NormalizedWorkweek} boundary strings, falling back to a single\n * pay-period-spanning workweek when the API returns no workweek boundaries.\n *\n * @param workweeks - The prepared payroll's top-level `workweeks` (RFCDate boundaries), possibly `null`.\n * @param payPeriod - The prepared payroll's `payPeriod`, used as the single-workweek fallback.\n * @returns One entry per workweek; a single entry spanning the pay period when none are supplied.\n * @throws SDKInternalError when neither workweeks nor a pay period are present (a malformed prepared payroll).\n * @internal\n */\nexport function normalizeWorkweeks(\n workweeks: Array<{ startDate?: RFCDate; endDate?: RFCDate }> | null | undefined,\n payPeriod: { startDate?: string; endDate?: string } | undefined,\n): NormalizedWorkweek[] {\n const normalized = (workweeks ?? []).flatMap(week =>\n week.startDate && week.endDate\n ? [{ startDate: week.startDate.toString(), endDate: week.endDate.toString() }]\n : [],\n )\n\n if (normalized.length > 0) {\n return normalized\n }\n\n if (payPeriod?.startDate && payPeriod.endDate) {\n return [{ startDate: payPeriod.startDate, endDate: payPeriod.endDate }]\n }\n\n // A prepared payroll always carries a pay period, so reaching here means the\n // response was malformed. Fail loud rather than build an empty, mis-keyed form\n // that could submit an employee's pay against a blank workweek.\n throw new SDKInternalError('Prepared payroll has no workweeks or pay period to derive from')\n}\n\n/**\n * Collects the names of earning types included in the regular-rate-of-pay\n * overtime calculation. These earnings render in the workweek-breakdown\n * additional-earnings section; all others fall into the flat `overtimeExcludedEarnings` section.\n *\n * @param earningTypeList - The company's default and custom earning types.\n * @returns A set of earning-type names with `includedInOvertimePay` set.\n * @internal\n */\nexport function collectOvertimeEarningNames(\n earningTypeList: EarningTypeList | undefined,\n): Set<string> {\n const names = new Set<string>()\n for (const earningType of [\n ...(earningTypeList?.default ?? []),\n ...(earningTypeList?.custom ?? []),\n ]) {\n if (earningType.name && earningType.includedInOvertimePay) {\n names.add(earningType.name)\n }\n }\n return names\n}\n\n/**\n * Merges the employee's existing fixed compensations with a blank placeholder for\n * every payroll fixed-compensation type they don't yet have, mirroring the stable editor\n * (`getAdditionalEarningsCompensations`). This is what lets the editor surface an\n * empty input for Bonus, Commission, etc. even when the prepared payroll carries\n * no fixed compensations. Placeholders attach to the primary job and carry no\n * amount (blank), so an untouched earning submits as zero without altering pay.\n *\n * @remarks\n * Owners (FLSA status `Owner`) never receive placeholders. Earning types that are\n * handled elsewhere or never shown as additional earnings\n * ({@link EXCLUDED_ADDITIONAL_EARNINGS}) and inactive types are skipped. The\n * result is sorted alphabetically by name. The regular-rate-of-pay split between\n * additional earnings and `overtimeExcludedEarnings` happens downstream via `overtimeEarningNames`;\n * this helper only decides which earning lines exist.\n *\n * @param existingFixedCompensations - The prepared compensation's fixed compensations.\n * @param fixedCompensationTypes - The prepared payroll's `fixedCompensationTypes` (the same source the stable editor uses).\n * @param primaryJobUuid - The employee's primary job UUID; placeholders attach here.\n * @param flsaStatus - The employee's FLSA status; owners get no placeholders.\n * @returns The merged, filtered, alphabetically sorted fixed-compensation lines.\n * @internal\n */\nexport function resolveEditableFixedCompensations(\n existingFixedCompensations: FixedCompensationEntry[] | undefined,\n fixedCompensationTypes: Array<{ name?: string | null }> | undefined,\n primaryJobUuid: string | undefined,\n flsaStatus: string | undefined,\n): FixedCompensationEntry[] {\n const merged: FixedCompensationEntry[] = [...(existingFixedCompensations ?? [])]\n\n if (flsaStatus !== FlsaStatus.OWNER && primaryJobUuid) {\n for (const compensationType of fixedCompensationTypes ?? []) {\n const name = compensationType.name\n if (!name) continue\n if (EXCLUDED_ADDITIONAL_EARNINGS.includes(name)) continue\n const exists = merged.some(entry => entry.name?.toLowerCase() === name.toLowerCase())\n if (!exists) merged.push({ name, jobUuid: primaryJobUuid })\n }\n }\n\n return merged\n .filter(entry => entry.name && !EXCLUDED_ADDITIONAL_EARNINGS.includes(entry.name))\n .sort((a, b) => (a.name ?? '').localeCompare(b.name ?? ''))\n}\n\n/**\n * Whether the employee's prepared compensation already carries non-zero\n * Overtime or Double-overtime hours.\n *\n * @remarks\n * Used to default the single `withOvertime` flag: an employee who already\n * has real overtime hours starts with the workweek split shown rather than\n * requiring an extra click to see data that's already there.\n *\n * @param hourlyCompensations - The prepared compensation's hourly lines.\n * @returns `true` when any Overtime or Double-overtime line has hours greater than zero.\n * @internal\n */\nexport function hasExistingOvertimeHours(\n hourlyCompensations: PayrollEmployeeCompensationsType['hourlyCompensations'] | undefined,\n): boolean {\n return (hourlyCompensations ?? []).some(\n compensation =>\n (compensation.name === COMPENSATION_NAME_OVERTIME ||\n compensation.name === COMPENSATION_NAME_DOUBLE_OVERTIME) &&\n parseFloat(compensation.hours ?? '0') > 0,\n )\n}\n\n/**\n * Whether a line's `breakdowns` exactly cover every workweek in `workweeks`\n * (each workweek has a breakdown entry matching both its start and end date).\n */\nfunction lineBreakdownsMatchWorkweeks(\n breakdowns: Array<{ startDate?: RFCDate; endDate?: RFCDate }> | undefined,\n workweeks: NormalizedWorkweek[],\n): boolean {\n if (!breakdowns || breakdowns.length === 0) return false\n return workweeks.every(workweek =>\n breakdowns.some(\n breakdown =>\n breakdown.startDate?.toString() === workweek.startDate &&\n breakdown.endDate?.toString() === workweek.endDate,\n ),\n )\n}\n\n/**\n * Whether any of the employee's hourly-compensation lines already carries a\n * real, per-workweek `breakdowns` array that exactly tiles the current pay\n * period's workweeks.\n *\n * @remarks\n * Used alongside {@link hasExistingOvertimeHours} to default the single\n * `withOvertime` flag: an employee whose hours are already broken down by\n * workweek (e.g. a previous edit entered real per-week values) starts with the\n * workweek split shown, seeded from those breakdowns rather than from a blank\n * or first-cell-only guess. See {@link buildWeekMap}, which applies the same\n * per-line check to decide each line's population mode.\n *\n * @param hourlyCompensations - The prepared compensation's hourly lines.\n * @param workweeks - Normalized workweeks for the pay period.\n * @returns `true` when at least one hourly line's breakdowns cover every workweek.\n * @internal\n */\nexport function hasBreakdownsMatchingWorkweeks(\n hourlyCompensations: PayrollEmployeeCompensationsType['hourlyCompensations'] | undefined,\n workweeks: NormalizedWorkweek[],\n): boolean {\n return (hourlyCompensations ?? []).some(compensation =>\n lineBreakdownsMatchWorkweeks(compensation.breakdowns, workweeks),\n )\n}\n\n/**\n * Trims an API decimal string (e.g. `\"40.000\"`, `\"500.00\"`) to a clean editable\n * value (`\"40\"`, `\"500\"`), preserving real fractional parts (`\"40.5\"`). A blank\n * or non-numeric value returns `''` (meaning \"not provided\").\n */\nfunction formatAmountInput(value: string | null | undefined): string {\n if (value == null || value === '') return ''\n const parsed = parseFloat(value)\n return Number.isNaN(parsed) ? '' : parsed.toString()\n}\n\n/**\n * Seeds a cell from a line's total: same as {@link formatAmountInput} except a\n * zero total yields `''` rather than `\"0\"`. A line whose total is zero (e.g. an\n * Overtime line with no overtime) should render as a blank cell the user can\n * fill in, not a pre-filled `0` — and a pre-filled `0` would also count as a\n * filled cell, tripping the per-row \"fill every workweek\" check for a line the\n * user never actually touched. Only used for total-seeded cells, never for real\n * per-week breakdown values (a genuine `0` breakdown must survive to keep a\n * matched split's tiling intact).\n */\nfunction formatSeededTotal(value: string | null | undefined): string {\n const formatted = formatAmountInput(value)\n return formatted === '0' ? '' : formatted\n}\n\n/**\n * Builds one job+name line's week map in one of three shapes, gated by\n * `isSplit` (`workweeks.length > 1 && isOvertimeEligible && withOvertime`):\n *\n * - Collapsed (`isSplit` false): a single key — the first workweek's start —\n * holding the total. No key is emitted for any other workweek, which is what\n * keeps a collapsed row's per-row validation a no-op (see\n * {@link createPayrollEditEmployeeSchema}).\n * - Split, breakdowns match ({@link hasBreakdownsMatchingWorkweeks} true for\n * this line): one key per workweek, each seeded from its real breakdown value.\n * - Split, no matching breakdowns: one key per workweek, with only the first\n * seeded (from the total) and the rest left blank — never auto-distributed,\n * so the user must fill them in (enforced by the schema's per-row check).\n */\nfunction buildWeekMap(\n workweeks: NormalizedWorkweek[],\n total: string | undefined,\n breakdowns:\n Array<{ startDate?: RFCDate; endDate?: RFCDate; hours?: string; amount?: string }> | undefined,\n isSplit: boolean,\n): Record<string, string> {\n const firstWorkweekStart = workweeks[0]?.startDate ?? ''\n\n if (!isSplit) {\n return { [firstWorkweekStart]: formatSeededTotal(total) }\n }\n\n const weekMap: Record<string, string> = {}\n if (lineBreakdownsMatchWorkweeks(breakdowns, workweeks)) {\n workweeks.forEach(workweek => {\n const breakdown = breakdowns?.find(\n entry => entry.startDate?.toString() === workweek.startDate,\n )\n weekMap[workweek.startDate] = formatAmountInput(breakdown?.hours ?? breakdown?.amount)\n })\n } else {\n workweeks.forEach((workweek, index) => {\n weekMap[workweek.startDate] = index === 0 ? formatSeededTotal(total) : ''\n })\n }\n return weekMap\n}\n\n/**\n * Derives the form's default values from the employee's prepared compensation.\n *\n * @remarks\n * Hourly and additional earnings are expanded into per-workweek maps via\n * {@link buildWeekMap}: collapsed to the total when not split, seeded from real\n * breakdowns or first-cell-only otherwise. Time off, final payout,\n * reimbursements, and payment method are read straight off the compensation.\n *\n * @param employeeCompensation - The employee's prepared compensation, if loaded.\n * @param workweeks - Normalized workweeks for the pay period.\n * @param withOvertime - The single, form-wide overtime-mode flag (see {@link hasExistingOvertimeHours}, {@link hasBreakdownsMatchingWorkweeks}, `actions.addOvertime`). Gates splitting alongside `isOvertimeEligible`.\n * @returns Default {@link PayrollEditEmployeeFormData} for `useForm`.\n * @internal\n */\nexport function derivePayrollEditEmployeeDefaults(\n employeeCompensation: PayrollEmployeeCompensationsType | undefined,\n workweeks: NormalizedWorkweek[],\n hasDirectDepositSetup: boolean,\n overtimeEarningNames: Set<string>,\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n fixedCompensations: FixedCompensationEntry[] = employeeCompensation?.fixedCompensations ?? [],\n): PayrollEditEmployeeFormData {\n // Only overtime-eligible employees split hours/earnings by workweek, and only\n // while the single `withOvertime` flag is on; everyone else renders (and\n // seeds) flat, even on a multi-workweek payroll.\n const isSplit = workweeks.length > 1 && isOvertimeEligible && withOvertime\n\n const hours: PayrollEditEmployeeFormData['hours'] = {}\n for (const compensation of employeeCompensation?.hourlyCompensations ?? []) {\n if (!compensation.jobUuid || !compensation.name) continue\n const jobHours = (hours[compensation.jobUuid] ??= {})\n jobHours[compensation.name] = buildWeekMap(\n workweeks,\n compensation.hours,\n compensation.breakdowns,\n isSplit,\n )\n }\n\n // Earnings whose earning type is included in the regular-rate-of-pay overtime\n // calculation stay workweek-breakdown; the rest are flat and land in `overtimeExcludedEarnings`.\n // The hook owns this bucketing so the UI just renders each section.\n const overtimeIncludedEarnings: PayrollEditEmployeeFormData['overtimeIncludedEarnings'] = {}\n const overtimeExcludedEarnings: PayrollEditEmployeeFormData['overtimeExcludedEarnings'] = {}\n for (const compensation of fixedCompensations) {\n if (!compensation.jobUuid || !compensation.name) continue\n if (overtimeEarningNames.has(compensation.name)) {\n const jobEarnings = (overtimeIncludedEarnings[compensation.jobUuid] ??= {})\n jobEarnings[compensation.name] = buildWeekMap(\n workweeks,\n compensation.amount,\n compensation.breakdowns,\n isSplit,\n )\n } else {\n const jobOther = (overtimeExcludedEarnings[compensation.jobUuid] ??= {})\n jobOther[compensation.name] = formatAmountInput(compensation.amount)\n }\n }\n\n const timeOff: PayrollEditEmployeeFormData['timeOff'] = {}\n const finalPayout: PayrollEditEmployeeFormData['finalPayout'] = {}\n for (const entry of employeeCompensation?.paidTimeOff ?? []) {\n if (!entry.name) continue\n timeOff[entry.name] = formatAmountInput(entry.hours)\n finalPayout[entry.name] = formatAmountInput(entry.finalPayoutUnusedHoursInput)\n }\n\n const reimbursements: PayrollEditEmployeeFormData['reimbursements'] = (\n employeeCompensation?.reimbursements ?? []\n ).map(reimbursement => ({\n uuid: reimbursement.uuid ?? null,\n description: reimbursement.description ?? '',\n amount: reimbursement.amount,\n recurring: reimbursement.recurring ?? false,\n }))\n\n return {\n hours,\n overtimeIncludedEarnings,\n overtimeExcludedEarnings,\n timeOff,\n finalPayout,\n reimbursements,\n reimbursementDraft: { description: '', amount: '' },\n paymentMethod: resolvePaymentMethod(employeeCompensation?.paymentMethod, hasDirectDepositSetup),\n }\n}\n\n/**\n * Resolves the default payment method, mirroring the stable component (#2683):\n * an employee with no direct deposit set up defaults to (and is forced to)\n * `Check`, even when the prepared payroll carried `Direct Deposit` or nothing.\n * `Historical` is treated as unset. The result is always `Direct Deposit` or\n * `Check` — never `Historical` — since those are the only values the update\n * endpoint accepts.\n */\nfunction resolvePaymentMethod(\n paymentMethod: string | null | undefined,\n hasDirectDepositSetup: boolean,\n): PayrollUpdatePaymentMethod {\n if (paymentMethod === PayrollUpdatePaymentMethod.Check) return PayrollUpdatePaymentMethod.Check\n if (paymentMethod === PayrollUpdatePaymentMethod.DirectDeposit && hasDirectDepositSetup) {\n return PayrollUpdatePaymentMethod.DirectDeposit\n }\n return hasDirectDepositSetup\n ? PayrollUpdatePaymentMethod.DirectDeposit\n : PayrollUpdatePaymentMethod.Check\n}\n\nfunction originalTotals<T extends { jobUuid?: string; name?: string }>(\n compensations: T[] | undefined,\n selectTotal: (compensation: T) => string | null | undefined,\n): Map<string, string> {\n const totals = new Map<string, string>()\n for (const compensation of compensations ?? []) {\n if (!compensation.jobUuid || !compensation.name) continue\n totals.set(`${compensation.jobUuid}|${compensation.name}`, selectTotal(compensation) ?? '')\n }\n return totals\n}\n\n// Precision of the per-workweek values being summed: dollar amounts carry cents,\n// hours up to six places.\nconst AMOUNT_DECIMALS = 2\nconst HOURS_DECIMALS = 6\n\n/**\n * Sums per-workweek input values in integer minor units, then scales back.\n *\n * @remarks\n * Each value is already bounded to `decimals` places, so scaling it to an\n * integer (cents for amounts, millionths for hours) and summing those integers\n * is exact. Float-accumulating the decimals directly and rounding at the end\n * would instead leak binary error into the wire value (e.g. `0.1 + 0.2` →\n * `\"0.30000000000000004\"`), which the payroll API should never receive.\n */\nfunction sumWeekValues(\n weekMap: Record<string, string>,\n workweeks: NormalizedWorkweek[],\n decimals: number,\n): string {\n const factor = 10 ** decimals\n const totalMinorUnits = workweeks.reduce((total, workweek) => {\n const value = parseFloat(weekMap[workweek.startDate] ?? '0') || 0\n return total + Math.round(value * factor)\n }, 0)\n return String(totalMinorUnits / factor)\n}\n\n/**\n * Builds the `PayrollUpdate` employee-compensation payload from form values.\n *\n * @remarks\n * When the pay period spans a single workweek (or the employee isn't split by\n * workweek), totals are sent without `breakdowns`. When split, each hourly and\n * additional-earning line is decided independently — per line, not per job\n * (the API models breakdowns on each compensation line, not as a per-job\n * all-or-nothing unit):\n *\n * - A fully-filled line (every workweek cell has a value) sends `breakdowns`\n * tiling every workweek exactly, with the total equal to the sum of the\n * per-week values.\n * - An entirely blank line sends nothing for it — no `breakdowns`, no\n * fabricated `0`, no fabricated total — leaving it as the flat, untouched\n * value it already was.\n * - A partial line (some but not all cells filled) can never reach this\n * function: {@link createPayrollEditEmployeeSchema}'s per-row check blocks\n * submit until every cell in a touched row is filled.\n *\n * @param formData - Current parsed form values.\n * @param employeeCompensation - The prepared compensation, for identifying metadata (`version`, `employeeUuid`).\n * @param workweeks - Normalized workweeks for the pay period.\n * @param payrollCategory - The payroll category, gating itemized vs. off-cycle reimbursements.\n * @param isOvertimeEligible - Whether the employee is overtime-eligible (nonexempt family).\n * @param withOvertime - The single, form-wide overtime-mode flag. Gates splitting alongside `isOvertimeEligible` and `workweeks.length > 1`; when `false`, every line submits its flat (collapsed) value regardless of eligibility.\n * @returns The employee-compensation entry for the `PayrollUpdate` request body.\n * @internal\n */\nexport function buildPayrollUpdateEmployeeCompensation(\n formData: PayrollEditEmployeeFormOutputs,\n employeeCompensation: PayrollEmployeeCompensationsType | undefined,\n workweeks: NormalizedWorkweek[],\n payrollCategory: PayrollCategory,\n isOvertimeEligible: boolean,\n withOvertime: boolean,\n): PayrollUpdateEmployeeCompensations {\n // Breakdowns are emitted only when the line is actually split by workweek:\n // multiple workweeks, an overtime-eligible employee, and `withOvertime` on.\n // This must match the field builder's gate so what renders and what submits\n // never drift.\n const isSplit = workweeks.length > 1 && isOvertimeEligible && withOvertime\n const hasValue = (value: string | undefined) => value != null && value !== ''\n const originalHours = originalTotals(\n employeeCompensation?.hourlyCompensations,\n comp => comp.hours,\n )\n const originalAmounts = originalTotals(\n employeeCompensation?.fixedCompensations,\n comp => comp.amount,\n )\n const isRowFilled = (weekMap: Record<string, string>) =>\n workweeks.every(workweek => hasValue(weekMap[workweek.startDate]))\n const collapsedValue = (\n jobUuid: string,\n name: string,\n weekMap: Record<string, string>,\n originals: Map<string, string>,\n ) => {\n const single = weekMap[workweeks[0]?.startDate ?? '']\n return hasValue(single) ? single! : (originals.get(`${jobUuid}|${name}`) ?? '0')\n }\n\n const hourlyCompensations = Object.entries(formData.hours).flatMap(([jobUuid, names]) =>\n Object.entries(names).flatMap(([name, weekMap]) => {\n if (!isSplit) {\n return [{ jobUuid, name, hours: collapsedValue(jobUuid, name, weekMap, originalHours) }]\n }\n if (!isRowFilled(weekMap)) return []\n return [\n {\n jobUuid,\n name,\n hours: sumWeekValues(weekMap, workweeks, HOURS_DECIMALS),\n breakdowns: workweeks.map(workweek => ({\n startDate: new RFCDate(workweek.startDate),\n endDate: new RFCDate(workweek.endDate),\n hours: weekMap[workweek.startDate]!,\n })),\n },\n ]\n }),\n )\n\n const breakdownEarnings = Object.entries(formData.overtimeIncludedEarnings).flatMap(\n ([jobUuid, names]) =>\n Object.entries(names).flatMap(([name, weekMap]) => {\n if (!isSplit) {\n return [\n { jobUuid, name, amount: collapsedValue(jobUuid, name, weekMap, originalAmounts) },\n ]\n }\n if (!isRowFilled(weekMap)) return []\n return [\n {\n jobUuid,\n name,\n amount: sumWeekValues(weekMap, workweeks, AMOUNT_DECIMALS),\n breakdowns: workweeks.map(workweek => ({\n startDate: new RFCDate(workweek.startDate),\n endDate: new RFCDate(workweek.endDate),\n amount: weekMap[workweek.startDate]!,\n })),\n },\n ]\n }),\n )\n\n // Non-overtime earnings never carry breakdowns; they are sent as flat totals.\n const flatEarnings = Object.entries(formData.overtimeExcludedEarnings).flatMap(\n ([jobUuid, names]) =>\n Object.entries(names).map(([name, amount]) => ({\n jobUuid,\n name,\n amount: hasValue(amount) ? amount : (originalAmounts.get(`${jobUuid}|${name}`) ?? '0'),\n })),\n )\n\n const fixedCompensations = [...breakdownEarnings, ...flatEarnings]\n\n const isDismissal = payrollCategory === PayrollCategory.Dismissal\n const paidTimeOff = Object.entries(formData.timeOff).map(([name, value]) => ({\n name,\n hours: value || '0',\n ...(isDismissal && formData.finalPayout[name] != null\n ? { finalPayoutUnusedHoursInput: formData.finalPayout[name] || '0' }\n : {}),\n }))\n\n const usesItemizedReimbursements = !isOffCyclePayroll(payrollCategory)\n\n return {\n employeeUuid: employeeCompensation?.employeeUuid,\n version: employeeCompensation?.version as string | undefined,\n excluded: employeeCompensation?.excluded,\n memo: employeeCompensation?.memo || undefined,\n ...(formData.paymentMethod ? { paymentMethod: formData.paymentMethod } : {}),\n hourlyCompensations,\n fixedCompensations,\n paidTimeOff,\n ...(usesItemizedReimbursements\n ? { reimbursements: cleanupReimbursements(formData.reimbursements) }\n : {}),\n }\n}\n"],"names":["normalizeWorkweeks","workweeks","payPeriod","normalized","week","SDKInternalError","collectOvertimeEarningNames","earningTypeList","names","earningType","resolveEditableFixedCompensations","existingFixedCompensations","fixedCompensationTypes","primaryJobUuid","flsaStatus","merged","FlsaStatus","compensationType","name","EXCLUDED_ADDITIONAL_EARNINGS","entry","a","b","hasExistingOvertimeHours","hourlyCompensations","compensation","COMPENSATION_NAME_OVERTIME","COMPENSATION_NAME_DOUBLE_OVERTIME","lineBreakdownsMatchWorkweeks","breakdowns","breakdown","workweek","hasBreakdownsMatchingWorkweeks","formatAmountInput","value","parsed","formatSeededTotal","formatted","buildWeekMap","total","isSplit","firstWorkweekStart","weekMap","index","derivePayrollEditEmployeeDefaults","employeeCompensation","hasDirectDepositSetup","overtimeEarningNames","isOvertimeEligible","withOvertime","fixedCompensations","hours","jobHours","overtimeIncludedEarnings","overtimeExcludedEarnings","jobEarnings","jobOther","timeOff","finalPayout","reimbursements","reimbursement","resolvePaymentMethod","paymentMethod","PayrollUpdatePaymentMethod","originalTotals","compensations","selectTotal","totals","AMOUNT_DECIMALS","HOURS_DECIMALS","sumWeekValues","decimals","factor","totalMinorUnits","buildPayrollUpdateEmployeeCompensation","formData","payrollCategory","hasValue","originalHours","comp","originalAmounts","isRowFilled","collapsedValue","jobUuid","originals","single","RFCDate","breakdownEarnings","flatEarnings","amount","isDismissal","PayrollCategory","paidTimeOff","usesItemizedReimbursements","isOffCyclePayroll","cleanupReimbursements"],"mappings":"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"}
@@ -3,44 +3,44 @@ import { PayrollUpdatePaymentMethod as i } from "@gusto/embedded-api/models/comp
3
3
  const f = [
4
4
  i.DirectDeposit,
5
5
  i.Check
6
- ], R = f.map((r) => ({ value: r, label: r })), a = {
6
+ ], I = f.map((r) => ({ value: r, label: r })), c = {
7
7
  NEGATIVE_AMOUNT: "NEGATIVE_AMOUNT",
8
8
  REIMBURSEMENT_AMOUNT: "REIMBURSEMENT_AMOUNT",
9
9
  REQUIRED_WORKWEEK: "REQUIRED_WORKWEEK"
10
10
  }, p = /^\d+(\.\d+)?$/, t = e.string().refine((r) => r === "" || p.test(r), {
11
- message: a.NEGATIVE_AMOUNT
11
+ message: c.NEGATIVE_AMOUNT
12
12
  }), M = e.object({
13
13
  uuid: e.string().nullable().optional(),
14
14
  description: e.string(),
15
15
  amount: e.string(),
16
16
  recurring: e.boolean().optional()
17
- }), A = e.object({
17
+ }), R = e.object({
18
18
  description: e.string(),
19
19
  amount: e.string().refine((r) => parseFloat(r) > 0, {
20
- message: a.REIMBURSEMENT_AMOUNT
20
+ message: c.REIMBURSEMENT_AMOUNT
21
21
  })
22
22
  });
23
- function c(r, o, E) {
24
- for (const [d, m] of Object.entries(o))
23
+ function a(r, n, E) {
24
+ for (const [d, m] of Object.entries(n))
25
25
  for (const [u, g] of Object.entries(m)) {
26
- const n = Object.entries(g);
27
- if (!(n.length <= 1 || !n.some(([, s]) => s !== "")))
28
- for (const [s, l] of n)
26
+ const o = Object.entries(g);
27
+ if (!(o.length <= 1 || !o.some(([, s]) => s !== "")))
28
+ for (const [s, l] of o)
29
29
  l === "" && r.addIssue({
30
30
  code: e.ZodIssueCode.custom,
31
- message: a.REQUIRED_WORKWEEK,
31
+ message: c.REQUIRED_WORKWEEK,
32
32
  path: [E, d, u, s]
33
33
  });
34
34
  }
35
35
  }
36
- function b() {
36
+ function A() {
37
37
  return e.object({
38
38
  hours: e.record(e.string(), e.record(e.string(), e.record(e.string(), t))),
39
- additionalEarnings: e.record(
39
+ overtimeIncludedEarnings: e.record(
40
40
  e.string(),
41
41
  e.record(e.string(), e.record(e.string(), t))
42
42
  ),
43
- other: e.record(e.string(), e.record(e.string(), t)),
43
+ overtimeExcludedEarnings: e.record(e.string(), e.record(e.string(), t)),
44
44
  timeOff: e.record(e.string(), t),
45
45
  finalPayout: e.record(e.string(), t),
46
46
  reimbursements: e.array(M),
@@ -49,15 +49,15 @@ function b() {
49
49
  // the payroll submit.
50
50
  reimbursementDraft: e.object({ description: e.string(), amount: e.string() }),
51
51
  paymentMethod: e.enum(i).optional()
52
- }).superRefine((r, o) => {
53
- c(o, r.hours, "hours"), c(o, r.additionalEarnings, "additionalEarnings");
52
+ }).superRefine((r, n) => {
53
+ a(n, r.hours, "hours"), a(n, r.overtimeIncludedEarnings, "overtimeIncludedEarnings");
54
54
  });
55
55
  }
56
56
  export {
57
- R as PAYMENT_METHOD_OPTIONS,
57
+ I as PAYMENT_METHOD_OPTIONS,
58
58
  f as PAYMENT_METHOD_VALUES,
59
- a as PayrollEditEmployeeErrorCodes,
60
- b as createPayrollEditEmployeeSchema,
61
- A as reimbursementDraftSchema
59
+ c as PayrollEditEmployeeErrorCodes,
60
+ A as createPayrollEditEmployeeSchema,
61
+ R as reimbursementDraftSchema
62
62
  };
63
63
  //# sourceMappingURL=payrollEditEmployeeSchema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"payrollEditEmployeeSchema.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.ts"],"sourcesContent":["import { z } from 'zod'\nimport { PayrollUpdatePaymentMethod } from '@gusto/embedded-api/models/components/payrollupdate'\n\n/**\n * Payment-method option values, in display order. The hook publishes these on\n * `fieldsMetadata.paymentMethod` via `withOptions`; the UI supplies the\n * translated labels through `getOptionLabel`.\n *\n * @internal\n */\nexport const PAYMENT_METHOD_VALUES = [\n PayrollUpdatePaymentMethod.DirectDeposit,\n PayrollUpdatePaymentMethod.Check,\n] as const\n\n/** @internal */\nexport const PAYMENT_METHOD_OPTIONS = PAYMENT_METHOD_VALUES.map(value => ({ value, label: value }))\n\n/**\n * Validation error codes produced by the payroll edit-employee schema.\n *\n * @public\n */\nexport const PayrollEditEmployeeErrorCodes = {\n NEGATIVE_AMOUNT: 'NEGATIVE_AMOUNT',\n REIMBURSEMENT_AMOUNT: 'REIMBURSEMENT_AMOUNT',\n REQUIRED_WORKWEEK: 'REQUIRED_WORKWEEK',\n} as const\n\n/**\n * Union of validation error codes emitted by the payroll edit-employee schema.\n *\n * @public\n */\nexport type PayrollEditEmployeeErrorCode =\n (typeof PayrollEditEmployeeErrorCodes)[keyof typeof PayrollEditEmployeeErrorCodes]\n\n// A plain, non-negative decimal: one or more digits with an optional fractional\n// part. Deliberately strict — `parseFloat` would accept \"5ea\" (→ 5), \"Infinity\",\n// and \"1e3\", any of which would silently corrupt the amount downstream.\nconst NON_NEGATIVE = /^\\d+(\\.\\d+)?$/\n\n// Hours and amounts are entered as strings. Blank is allowed (it means \"not\n// provided\" — see the submit rule), but any provided value must be a valid,\n// non-negative number.\nconst nonNegativeAmount = z.string().refine(value => value === '' || NON_NEGATIVE.test(value), {\n message: PayrollEditEmployeeErrorCodes.NEGATIVE_AMOUNT,\n})\n\n// Committed reimbursement rows are presentational passthrough: they hold data\n// that was already validated when its draft was saved (or came from the server),\n// so the amount is a plain string here. All reimbursement validation lives in\n// `reimbursementDraftSchema` below, mirroring the legacy editor.\nconst reimbursementSchema = z.object({\n uuid: z.string().nullable().optional(),\n description: z.string(),\n amount: z.string(),\n recurring: z.boolean().optional(),\n})\n\n/**\n * The single reimbursement validation schema: the \"add reimbursement\" draft row.\n * Amount must be a number greater than zero, matching the legacy editor's\n * inline validation. The hook validates the draft against this before committing\n * it to the presentational `reimbursements` list.\n *\n * @internal\n */\nexport const reimbursementDraftSchema = z.object({\n description: z.string(),\n amount: z.string().refine(value => parseFloat(value) > 0, {\n message: PayrollEditEmployeeErrorCodes.REIMBURSEMENT_AMOUNT,\n }),\n})\n\n// A \"row\" is one job+name line's week map (`{ [workweekStart]: amount }`). A\n// collapsed (non-split) row always has exactly one key, so `entries.length <= 1`\n// makes this a no-op for collapsed rows — only a split row (multiple workweek\n// keys) can be \"partial.\" See the module-level remarks on {@link createPayrollEditEmployeeSchema}.\nfunction addRequiredWorkweekIssues(\n ctx: z.RefinementCtx,\n section: Record<string, Record<string, Record<string, string>>>,\n sectionKey: 'hours' | 'additionalEarnings',\n): void {\n for (const [jobUuid, names] of Object.entries(section)) {\n for (const [name, weekMap] of Object.entries(names)) {\n const entries = Object.entries(weekMap)\n if (entries.length <= 1) continue\n const hasAnyValue = entries.some(([, value]) => value !== '')\n if (!hasAnyValue) continue\n for (const [workweekStart, value] of entries) {\n if (value === '') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: PayrollEditEmployeeErrorCodes.REQUIRED_WORKWEEK,\n path: [sectionKey, jobUuid, name, workweekStart],\n })\n }\n }\n }\n }\n}\n\n/**\n * Builds the Zod schema for the payroll edit-employee form.\n *\n * @remarks\n * Overtime-affecting values are keyed by workweek internally: hours and\n * additional earnings are job-then-name-then-workweekStart records, so the\n * single-workweek (or not-yet-split) case is just the degenerate one-key form\n * of the multi-workweek shape. Non-overtime earnings (other) are flat\n * job-then-name-to-amount records with no per-workweek breakdown, since they do\n * not feed the blended rate. Time off and final payout are keyed by\n * compensation name. This keeps one schema and one submit path.\n *\n * A `superRefine` enforces per-row completeness on `hours` and\n * `additionalEarnings`: once any workweek cell in a job+name row is filled, every\n * other cell in that row must be filled too, surfaced per empty cell as\n * {@link PayrollEditEmployeeErrorCodes.REQUIRED_WORKWEEK}. A row with nothing\n * filled is left alone (still submittable as untouched). This needs no\n * workweek/split context passed in — it's purely structural on whatever keys a\n * row happens to have, which is why a collapsed row (always exactly one key)\n * can never trigger it.\n *\n * @returns The Zod schema validating {@link PayrollEditEmployeeFormData}.\n * @internal\n */\nexport function createPayrollEditEmployeeSchema() {\n return z\n .object({\n hours: z.record(z.string(), z.record(z.string(), z.record(z.string(), nonNegativeAmount))),\n additionalEarnings: z.record(\n z.string(),\n z.record(z.string(), z.record(z.string(), nonNegativeAmount)),\n ),\n other: z.record(z.string(), z.record(z.string(), nonNegativeAmount)),\n timeOff: z.record(z.string(), nonNegativeAmount),\n finalPayout: z.record(z.string(), nonNegativeAmount),\n reimbursements: z.array(reimbursementSchema),\n // Binding shape only — the draft is validated against `reimbursementDraftSchema`\n // at save time, not by the main resolver, so a half-filled draft never blocks\n // the payroll submit.\n reimbursementDraft: z.object({ description: z.string(), amount: z.string() }),\n paymentMethod: z.enum(PayrollUpdatePaymentMethod).optional(),\n })\n .superRefine((data, ctx) => {\n addRequiredWorkweekIssues(ctx, data.hours, 'hours')\n addRequiredWorkweekIssues(ctx, data.additionalEarnings, 'additionalEarnings')\n })\n}\n\n/**\n * Shape of the values managed by the payroll edit-employee form.\n *\n * @public\n */\nexport type PayrollEditEmployeeFormData = z.infer<\n ReturnType<typeof createPayrollEditEmployeeSchema>\n>\n\n/**\n * Validated values produced by the payroll edit-employee form on submit.\n *\n * @internal\n */\nexport type PayrollEditEmployeeFormOutputs = PayrollEditEmployeeFormData\n\n/**\n * A single reimbursement row in {@link PayrollEditEmployeeFormData}.\n *\n * @public\n */\nexport type ReimbursementFormEntry = PayrollEditEmployeeFormData['reimbursements'][number]\n"],"names":["PAYMENT_METHOD_VALUES","PayrollUpdatePaymentMethod","PAYMENT_METHOD_OPTIONS","value","PayrollEditEmployeeErrorCodes","NON_NEGATIVE","nonNegativeAmount","z","reimbursementSchema","reimbursementDraftSchema","addRequiredWorkweekIssues","ctx","section","sectionKey","jobUuid","names","name","weekMap","entries","workweekStart","createPayrollEditEmployeeSchema","data"],"mappings":";;AAUO,MAAMA,IAAwB;AAAA,EACnCC,EAA2B;AAAA,EAC3BA,EAA2B;AAC7B,GAGaC,IAAyBF,EAAsB,IAAI,CAAAG,OAAU,EAAE,OAAAA,GAAO,OAAOA,IAAQ,GAOrFC,IAAgC;AAAA,EAC3C,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,mBAAmB;AACrB,GAaMC,IAAe,iBAKfC,IAAoBC,EAAE,OAAA,EAAS,OAAO,CAAAJ,MAASA,MAAU,MAAME,EAAa,KAAKF,CAAK,GAAG;AAAA,EAC7F,SAASC,EAA8B;AACzC,CAAC,GAMKI,IAAsBD,EAAE,OAAO;AAAA,EACnC,MAAMA,EAAE,OAAA,EAAS,SAAA,EAAW,SAAA;AAAA,EAC5B,aAAaA,EAAE,OAAA;AAAA,EACf,QAAQA,EAAE,OAAA;AAAA,EACV,WAAWA,EAAE,QAAA,EAAU,SAAA;AACzB,CAAC,GAUYE,IAA2BF,EAAE,OAAO;AAAA,EAC/C,aAAaA,EAAE,OAAA;AAAA,EACf,QAAQA,EAAE,OAAA,EAAS,OAAO,CAAAJ,MAAS,WAAWA,CAAK,IAAI,GAAG;AAAA,IACxD,SAASC,EAA8B;AAAA,EAAA,CACxC;AACH,CAAC;AAMD,SAASM,EACPC,GACAC,GACAC,GACM;AACN,aAAW,CAACC,GAASC,CAAK,KAAK,OAAO,QAAQH,CAAO;AACnD,eAAW,CAACI,GAAMC,CAAO,KAAK,OAAO,QAAQF,CAAK,GAAG;AACnD,YAAMG,IAAU,OAAO,QAAQD,CAAO;AAGtC,UAFI,EAAAC,EAAQ,UAAU,KAElB,CADgBA,EAAQ,KAAK,CAAC,CAAA,EAAGf,CAAK,MAAMA,MAAU,EAAE;AAE5D,mBAAW,CAACgB,GAAehB,CAAK,KAAKe;AACnC,UAAIf,MAAU,MACZQ,EAAI,SAAS;AAAA,YACX,MAAMJ,EAAE,aAAa;AAAA,YACrB,SAASH,EAA8B;AAAA,YACvC,MAAM,CAACS,GAAYC,GAASE,GAAMG,CAAa;AAAA,UAAA,CAChD;AAAA,IAGP;AAEJ;AA0BO,SAASC,IAAkC;AAChD,SAAOb,EACJ,OAAO;AAAA,IACN,OAAOA,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,UAAUD,CAAiB,CAAC,CAAC;AAAA,IACzF,oBAAoBC,EAAE;AAAA,MACpBA,EAAE,OAAA;AAAA,MACFA,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB,CAAC;AAAA,IAAA;AAAA,IAE9D,OAAOC,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB,CAAC;AAAA,IACnE,SAASC,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB;AAAA,IAC/C,aAAaC,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB;AAAA,IACnD,gBAAgBC,EAAE,MAAMC,CAAmB;AAAA;AAAA;AAAA;AAAA,IAI3C,oBAAoBD,EAAE,OAAO,EAAE,aAAaA,EAAE,OAAA,GAAU,QAAQA,EAAE,OAAA,EAAO,CAAG;AAAA,IAC5E,eAAeA,EAAE,KAAKN,CAA0B,EAAE,SAAA;AAAA,EAAS,CAC5D,EACA,YAAY,CAACoB,GAAMV,MAAQ;AAC1B,IAAAD,EAA0BC,GAAKU,EAAK,OAAO,OAAO,GAClDX,EAA0BC,GAAKU,EAAK,oBAAoB,oBAAoB;AAAA,EAC9E,CAAC;AACL;"}
1
+ {"version":3,"file":"payrollEditEmployeeSchema.js","sources":["../../../../../../src/components/Payroll/PayrollEditEmployee/shared/usePayrollEditEmployeeForm/payrollEditEmployeeSchema.ts"],"sourcesContent":["import { z } from 'zod'\nimport { PayrollUpdatePaymentMethod } from '@gusto/embedded-api/models/components/payrollupdate'\n\n/**\n * Payment-method option values, in display order. The hook publishes these on\n * `fieldsMetadata.paymentMethod` via `withOptions`; the UI supplies the\n * translated labels through `getOptionLabel`.\n *\n * @internal\n */\nexport const PAYMENT_METHOD_VALUES = [\n PayrollUpdatePaymentMethod.DirectDeposit,\n PayrollUpdatePaymentMethod.Check,\n] as const\n\n/** @internal */\nexport const PAYMENT_METHOD_OPTIONS = PAYMENT_METHOD_VALUES.map(value => ({ value, label: value }))\n\n/**\n * Validation error codes produced by the payroll edit-employee schema.\n *\n * @public\n */\nexport const PayrollEditEmployeeErrorCodes = {\n NEGATIVE_AMOUNT: 'NEGATIVE_AMOUNT',\n REIMBURSEMENT_AMOUNT: 'REIMBURSEMENT_AMOUNT',\n REQUIRED_WORKWEEK: 'REQUIRED_WORKWEEK',\n} as const\n\n/**\n * Union of validation error codes emitted by the payroll edit-employee schema.\n *\n * @public\n */\nexport type PayrollEditEmployeeErrorCode =\n (typeof PayrollEditEmployeeErrorCodes)[keyof typeof PayrollEditEmployeeErrorCodes]\n\n// A plain, non-negative decimal: one or more digits with an optional fractional\n// part. Deliberately strict — `parseFloat` would accept \"5ea\" (→ 5), \"Infinity\",\n// and \"1e3\", any of which would silently corrupt the amount downstream.\nconst NON_NEGATIVE = /^\\d+(\\.\\d+)?$/\n\n// Hours and amounts are entered as strings. Blank is allowed (it means \"not\n// provided\" — see the submit rule), but any provided value must be a valid,\n// non-negative number.\nconst nonNegativeAmount = z.string().refine(value => value === '' || NON_NEGATIVE.test(value), {\n message: PayrollEditEmployeeErrorCodes.NEGATIVE_AMOUNT,\n})\n\n// Committed reimbursement rows are presentational passthrough: they hold data\n// that was already validated when its draft was saved (or came from the server),\n// so the amount is a plain string here. All reimbursement validation lives in\n// `reimbursementDraftSchema` below, mirroring the legacy editor.\nconst reimbursementSchema = z.object({\n uuid: z.string().nullable().optional(),\n description: z.string(),\n amount: z.string(),\n recurring: z.boolean().optional(),\n})\n\n/**\n * The single reimbursement validation schema: the \"add reimbursement\" draft row.\n * Amount must be a number greater than zero, matching the legacy editor's\n * inline validation. The hook validates the draft against this before committing\n * it to the presentational `reimbursements` list.\n *\n * @internal\n */\nexport const reimbursementDraftSchema = z.object({\n description: z.string(),\n amount: z.string().refine(value => parseFloat(value) > 0, {\n message: PayrollEditEmployeeErrorCodes.REIMBURSEMENT_AMOUNT,\n }),\n})\n\n// A \"row\" is one job+name line's week map (`{ [workweekStart]: amount }`). A\n// collapsed (non-split) row always has exactly one key, so `entries.length <= 1`\n// makes this a no-op for collapsed rows — only a split row (multiple workweek\n// keys) can be \"partial.\" See the module-level remarks on {@link createPayrollEditEmployeeSchema}.\nfunction addRequiredWorkweekIssues(\n ctx: z.RefinementCtx,\n section: Record<string, Record<string, Record<string, string>>>,\n sectionKey: 'hours' | 'overtimeIncludedEarnings',\n): void {\n for (const [jobUuid, names] of Object.entries(section)) {\n for (const [name, weekMap] of Object.entries(names)) {\n const entries = Object.entries(weekMap)\n if (entries.length <= 1) continue\n const hasAnyValue = entries.some(([, value]) => value !== '')\n if (!hasAnyValue) continue\n for (const [workweekStart, value] of entries) {\n if (value === '') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: PayrollEditEmployeeErrorCodes.REQUIRED_WORKWEEK,\n path: [sectionKey, jobUuid, name, workweekStart],\n })\n }\n }\n }\n }\n}\n\n/**\n * Builds the Zod schema for the payroll edit-employee form.\n *\n * @remarks\n * Overtime-affecting values are keyed by workweek internally: hours and\n * additional earnings are job-then-name-then-workweekStart records, so the\n * single-workweek (or not-yet-split) case is just the degenerate one-key form\n * of the multi-workweek shape. Non-overtime earnings (`overtimeExcludedEarnings`) are flat\n * job-then-name-to-amount records with no per-workweek breakdown, since they do\n * not feed the blended rate. Time off and final payout are keyed by\n * compensation name. This keeps one schema and one submit path.\n *\n * A `superRefine` enforces per-row completeness on `hours` and\n * `overtimeIncludedEarnings`: once any workweek cell in a job+name row is filled, every\n * other cell in that row must be filled too, surfaced per empty cell as\n * {@link PayrollEditEmployeeErrorCodes.REQUIRED_WORKWEEK}. A row with nothing\n * filled is left alone (still submittable as untouched). This needs no\n * workweek/split context passed in — it's purely structural on whatever keys a\n * row happens to have, which is why a collapsed row (always exactly one key)\n * can never trigger it.\n *\n * @returns The Zod schema validating {@link PayrollEditEmployeeFormData}.\n * @internal\n */\nexport function createPayrollEditEmployeeSchema() {\n return z\n .object({\n hours: z.record(z.string(), z.record(z.string(), z.record(z.string(), nonNegativeAmount))),\n overtimeIncludedEarnings: z.record(\n z.string(),\n z.record(z.string(), z.record(z.string(), nonNegativeAmount)),\n ),\n overtimeExcludedEarnings: z.record(z.string(), z.record(z.string(), nonNegativeAmount)),\n timeOff: z.record(z.string(), nonNegativeAmount),\n finalPayout: z.record(z.string(), nonNegativeAmount),\n reimbursements: z.array(reimbursementSchema),\n // Binding shape only — the draft is validated against `reimbursementDraftSchema`\n // at save time, not by the main resolver, so a half-filled draft never blocks\n // the payroll submit.\n reimbursementDraft: z.object({ description: z.string(), amount: z.string() }),\n paymentMethod: z.enum(PayrollUpdatePaymentMethod).optional(),\n })\n .superRefine((data, ctx) => {\n addRequiredWorkweekIssues(ctx, data.hours, 'hours')\n addRequiredWorkweekIssues(ctx, data.overtimeIncludedEarnings, 'overtimeIncludedEarnings')\n })\n}\n\n/**\n * Shape of the values managed by the payroll edit-employee form.\n *\n * @public\n */\nexport type PayrollEditEmployeeFormData = z.infer<\n ReturnType<typeof createPayrollEditEmployeeSchema>\n>\n\n/**\n * Validated values produced by the payroll edit-employee form on submit.\n *\n * @internal\n */\nexport type PayrollEditEmployeeFormOutputs = PayrollEditEmployeeFormData\n\n/**\n * A single reimbursement row in {@link PayrollEditEmployeeFormData}.\n *\n * @public\n */\nexport type ReimbursementFormEntry = PayrollEditEmployeeFormData['reimbursements'][number]\n"],"names":["PAYMENT_METHOD_VALUES","PayrollUpdatePaymentMethod","PAYMENT_METHOD_OPTIONS","value","PayrollEditEmployeeErrorCodes","NON_NEGATIVE","nonNegativeAmount","z","reimbursementSchema","reimbursementDraftSchema","addRequiredWorkweekIssues","ctx","section","sectionKey","jobUuid","names","name","weekMap","entries","workweekStart","createPayrollEditEmployeeSchema","data"],"mappings":";;AAUO,MAAMA,IAAwB;AAAA,EACnCC,EAA2B;AAAA,EAC3BA,EAA2B;AAC7B,GAGaC,IAAyBF,EAAsB,IAAI,CAAAG,OAAU,EAAE,OAAAA,GAAO,OAAOA,IAAQ,GAOrFC,IAAgC;AAAA,EAC3C,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,mBAAmB;AACrB,GAaMC,IAAe,iBAKfC,IAAoBC,EAAE,OAAA,EAAS,OAAO,CAAAJ,MAASA,MAAU,MAAME,EAAa,KAAKF,CAAK,GAAG;AAAA,EAC7F,SAASC,EAA8B;AACzC,CAAC,GAMKI,IAAsBD,EAAE,OAAO;AAAA,EACnC,MAAMA,EAAE,OAAA,EAAS,SAAA,EAAW,SAAA;AAAA,EAC5B,aAAaA,EAAE,OAAA;AAAA,EACf,QAAQA,EAAE,OAAA;AAAA,EACV,WAAWA,EAAE,QAAA,EAAU,SAAA;AACzB,CAAC,GAUYE,IAA2BF,EAAE,OAAO;AAAA,EAC/C,aAAaA,EAAE,OAAA;AAAA,EACf,QAAQA,EAAE,OAAA,EAAS,OAAO,CAAAJ,MAAS,WAAWA,CAAK,IAAI,GAAG;AAAA,IACxD,SAASC,EAA8B;AAAA,EAAA,CACxC;AACH,CAAC;AAMD,SAASM,EACPC,GACAC,GACAC,GACM;AACN,aAAW,CAACC,GAASC,CAAK,KAAK,OAAO,QAAQH,CAAO;AACnD,eAAW,CAACI,GAAMC,CAAO,KAAK,OAAO,QAAQF,CAAK,GAAG;AACnD,YAAMG,IAAU,OAAO,QAAQD,CAAO;AAGtC,UAFI,EAAAC,EAAQ,UAAU,KAElB,CADgBA,EAAQ,KAAK,CAAC,CAAA,EAAGf,CAAK,MAAMA,MAAU,EAAE;AAE5D,mBAAW,CAACgB,GAAehB,CAAK,KAAKe;AACnC,UAAIf,MAAU,MACZQ,EAAI,SAAS;AAAA,YACX,MAAMJ,EAAE,aAAa;AAAA,YACrB,SAASH,EAA8B;AAAA,YACvC,MAAM,CAACS,GAAYC,GAASE,GAAMG,CAAa;AAAA,UAAA,CAChD;AAAA,IAGP;AAEJ;AA0BO,SAASC,IAAkC;AAChD,SAAOb,EACJ,OAAO;AAAA,IACN,OAAOA,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,UAAUD,CAAiB,CAAC,CAAC;AAAA,IACzF,0BAA0BC,EAAE;AAAA,MAC1BA,EAAE,OAAA;AAAA,MACFA,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB,CAAC;AAAA,IAAA;AAAA,IAE9D,0BAA0BC,EAAE,OAAOA,EAAE,OAAA,GAAUA,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB,CAAC;AAAA,IACtF,SAASC,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB;AAAA,IAC/C,aAAaC,EAAE,OAAOA,EAAE,OAAA,GAAUD,CAAiB;AAAA,IACnD,gBAAgBC,EAAE,MAAMC,CAAmB;AAAA;AAAA;AAAA;AAAA,IAI3C,oBAAoBD,EAAE,OAAO,EAAE,aAAaA,EAAE,OAAA,GAAU,QAAQA,EAAE,OAAA,EAAO,CAAG;AAAA,IAC5E,eAAeA,EAAE,KAAKN,CAA0B,EAAE,SAAA;AAAA,EAAS,CAC5D,EACA,YAAY,CAACoB,GAAMV,MAAQ;AAC1B,IAAAD,EAA0BC,GAAKU,EAAK,OAAO,OAAO,GAClDX,EAA0BC,GAAKU,EAAK,0BAA0B,0BAA0B;AAAA,EAC1F,CAAC;AACL;"}