Repository navigation
feat(invoice-schedule): add the semi-monthly invoicing cycle fieldset - #1765
Merged
Merged
Conversation
…quencies Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A recurring invoice schedule now asks for an end date choice: "No end date" or "End after a number of occurrences". The count only appears, and is only required (at least 1), for the second option. Both are hidden for a one-off. The fields sit right after the start date, and a saved schedule prefills the choice from its occurrence count. The choice is form-only: "No end date" still omits nr_occurrences from the request. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…oice Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…fter is picked The platform defaults the count to 1 once "End after a number of occurrences" is selected. The schema can't express that, so a form hook sets it when the end type changes to multiple and the count is still empty. Used by the standalone flow and the contractor onboarding step. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…en end after is picked" This reverts commit f34c672. A schema-level default for revealed fields is handled separately. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A field with a schema default that becomes visible after the form mounts is filled with that default if it is still empty. Fields visible on first render, read-only and forced-value fields are left alone. Uses it for the invoice schedule occurrence count, which now starts at 1 once "End after a number of occurrences" is picked. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… revealed The form can render with no fields while its schema loads. The empty list was recorded as the baseline, so every field that then appeared with a default was filled in. The baseline now starts at the first render that has fields. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ds instead of a form-wide hook The standalone flow builds its form before the schema loads, so a schema default was never read. It now runs the same initial-values helper the other flows use once its fields arrive, and fills only values that are still empty. The generic reveal-time hook is removed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…m like the other flows The form was created in InvoiceScheduleFlow before the schema loaded, so schema defaults could not feed its initial values. InvoiceScheduleForm now mounts once the fields exist and builds its values with getInitialValues, as the onboarding and termination forms do. The flow keeps the bag, the form id and a ref the preview button reads the live values from. The one-off seeding effect is removed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…eRefObject Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ecord reset The preview button now reads the latest values from the bag, which the form reports through checkFieldUpdates, so the form no longer registers itself in a ref. The flow is keyed by employmentId, so a different contractor starts from a fresh form. The frequency reset for a Contractor of Record is removed: the schema already rejects a frequency it no longer offers, and onboarding has no such reset. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…er from InvoiceScheduleFlow Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nt wrapper from InvoiceScheduleFlow" Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e them on the bag Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…form on isLoading like the other flows Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… already-cached contractor Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… bag members, tidy leftovers Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…alues Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Contributor
📦 Bundle Size Report
Size Limits
Largest Files (Top 5)
View All Files (301 total)
✅ Bundle size check passed |
Contributor
|
Deploy preview for adp-cost-calculator ready!
Deployed with vercel-action |
Contributor
|
Deploy preview for remote-flows ready!
Deployed with vercel-action |
…st access Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Contributor
📊 Coverage Report✅ Coverage increased! 🎉
Detailed BreakdownLines Coverage
Statements Coverage
Functions Coverage
Branches Coverage
✅ Coverage check passed |
… schema Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2 tasks
…ly cycle Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
3 tasks done
…-semi-monthly-cycle # Conflicts: # src/common/invoice-schedules/json-schema.ts # src/common/tests/invoice-schedules.test.ts # src/flows/InvoiceSchedule/tests/InvoiceScheduleFlow.test.tsx
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c96b10c. Configure here.
) * feat(invoice-schedule): group the onboarding step under fieldsets Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix(invoice-schedule): group the schedule summary under invoicing preferences * test(invoice-schedule): handle optional fieldsets in the grouping test --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
cammellos
approved these changes
Oct 29, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
I left some things in this one
The second field is a force field value, if we want to put a select I need to make changes to the SDK core
When you select semi-monthly, in platform they're able to disable array of days, not possible at the moment, requires another SDK core change
Summary
Choosing "Semi-monthly" on an invoice schedule now offers the same invoicing cycle choice as the Remote platform: the 15th and last day of the month, or a custom cycle.
Why
The standalone Invoice Schedule flow showed two free-form day inputs (1–31) for semi-monthly. The platform instead offers a radio and, for a custom cycle, a first day (1st–14th) with the second day fixed 14 days later. This brings the flow in line.
What changed
Toggle details
custom_day_1/custom_day_2number inputs. TheincludeCustomDaysoption is removed: the fieldset is part of the schema everywhere, so the in-flow onboarding step shows it too.constand statement are computed from the first day, the same way Tiger's computed read-only fields (e.g. CANavg_salary) work. No form code, no shared component change. The SDK sets the value of aconstfield and renders its statement.custom_days: [15, 31]for the default cycle (the API treats 31 as the last day of the month) and[first, first + 14]for a custom one. Before, nothing was sent unless both days were filled in.start_dateis validated against the cycle in the schema (x-jsf-logic-validations): the 15th or the last day of the month for the default cycle (leap years handled), the first or second day for a custom one. Any other date fails with "Choose a date that matches the selected invoicing cycle", the same rule the platform's invoice form applies.numbertypes.constfield renders as a statement).mainonce it merges.Screenshots
Toggle screenshots
Default cycle, and a custom cycle with the 3rd as the first day (the second is the 17th). Example app against sandbox, PRT contractor.
Open as a gallery (⌘-click or Ctrl-click for a new tab): click a screenshot, then use the arrow keys.
Default cycle
Custom cycle
Related Resources
Testing
InvoiceScheduleFlow.test.tsxcovers the default cycle ([15, 31]), a custom cycle ([3, 17]), no cycle for another frequency, and a start date outside the cycle being rejected. Unit tests coverbuildCustomDays,toOrdinal, the schema and the start date rule for both cycles.example/app in a browser (sandbox, PRT contractor)🤖 Generated with Claude Code
Note
Medium Risk
Changes how semi-monthly schedules are built and validated before API submit; wrong cycle or date logic could block creates or send unexpected
custom_days, though coverage is extensive.Overview
Semi-monthly invoice scheduling now matches the Remote platform instead of two free-form day inputs.
When Semi-monthly is selected, a Semi-monthly fieldset appears with an Invoicing cycle radio: default 15th and last day of the month (payload
custom_days: [15, 31]) or Custom cycle with a first-day select (1st–14th) and a read-only second day computed as first + 14 days. The schema optionincludeCustomDaysis replaced byincludeFieldsets, which optionally groups the whole form under platform headings (Invoicing details, Invoice items, Invoicing preferences, Summary). Onboarding passesincludeFieldsets: true; the standalone Invoice Schedule flow stays flat.start_dateis validated in the JSON schema so it must fall on a cycle day (including month-end and leap-year rules for the default cycle).buildCustomDays,buildInvoiceScheduleFormValues, and round-trip from savedcustom_dayswere updated for the newsemi_monthly_settingsshape. Docs and tests cover payloads, fieldsets, and start-date validation.Reviewed by Cursor Bugbot for commit 83725a3. Bugbot is set up for automated code reviews on this repo. Configure here.