diff --git a/_reference/commission-based-cut-manual-test-plan.md b/_reference/commission-based-cut-manual-test-plan.md
new file mode 100644
index 000000000..df94cc3f4
--- /dev/null
+++ b/_reference/commission-based-cut-manual-test-plan.md
@@ -0,0 +1,424 @@
+# Commission-Based Cut Feature Manual Test Plan
+
+## Purpose
+Use this guide to manually test the commission-based cut feature from an end-user point of view.
+
+This plan is written for a non-technical tester. Follow the steps exactly as written and mark each scenario as Pass or Fail.
+
+## What You Need Before You Start
+- A login that can open `Manage my Shop`, `Jobs`, and `Time Tickets`.
+- At least 2 active employees in the shop.
+- At least 1 converted repair order that already has labor lines on it.
+- If possible, use a simple test job where the labor sale rates are easy to calculate.
+- A notebook, spreadsheet, or screenshot folder to record what happened.
+
+## Recommended Easy-Math Test Data
+If you can choose your own test job, use something simple like this:
+
+- Body sale rate: `$100.00`
+- Refinish sale rate: `$120.00`
+- Mechanical sale rate: `$80.00`
+- 1 Body labor line with `10.0` hours
+- 1 Refinish labor line with `4.0` hours
+
+This makes the expected payout easy to check:
+
+- `40%` of `$100.00` = `$40.00`
+- `30%` of `$120.00` = `$36.00`
+
+## Important Navigation Notes
+- Team setup is under `Manage my Shop` > `Employee Teams`.
+- Team assignment happens on the job line grid in the `Team` column.
+- Automatic payout happens from the job's `Labor Allocations` card using the `Pay All` button.
+- If your shop uses task presets, the `Flag Hours` button can preview the payout method before committing tickets.
+
+---
+
+## Scenario 1: Create a Simple Commission Team
+### Goal
+Confirm a team member can be set to commission and saved successfully.
+
+### Steps
+1. Sign in.
+2. Click `Manage my Shop`.
+3. Click the `Employee Teams` tab.
+4. Click `New Team`.
+5. In `Team Name`, type `Commission Team Test`.
+6. Make sure `Active` is turned on.
+7. In `Max Load`, enter `10`.
+8. Click `New Team Member`.
+9. In `Employee`, choose an active employee.
+10. In `Allocation %`, enter `100`.
+11. In `Payout Method`, choose `Commission %`.
+12. In each commission field that appears, enter a value.
+13. For the main labor types you plan to test, use these values:
+14. Enter `40` for Body.
+15. Enter `30` for Refinish.
+16. Enter `25` for Mechanical.
+17. Enter `20` for Frame.
+18. Enter `15` for Glass.
+19. Fill in the remaining commission boxes with any valid number from `0` to `100`.
+20. Click `Save`.
+
+### Expected Result
+- The team saves successfully.
+- The team stays visible in the Employee Teams list.
+- The team member card shows a `Commission` tag.
+- The `Allocation Total` shows `100%`.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 2: Allocation Total Must Equal 100%
+### Goal
+Confirm the system blocks a team that does not total exactly 100%.
+
+### Steps
+1. Stay on the same team.
+2. Change `Allocation %` from `100` to `90`.
+3. Click `Save`.
+4. Change `Allocation %` from `90` to `110`.
+5. Click `Save`.
+6. Change `Allocation %` back to `100`.
+7. Click `Save` again.
+
+### Expected Result
+- When the total is `90%`, the system should not save.
+- When the total is `110%`, the system should not save.
+- The page should show that the allocation total is not correct.
+- When the total is set back to `100%`, the save should succeed.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 3: The Same Employee Cannot Be Added Twice
+### Goal
+Confirm the same employee cannot appear twice on one team.
+
+### Steps
+1. Open the same team again.
+2. Click `New Team Member`.
+3. Choose the same employee already used on the team.
+4. Enter any valid allocation amount.
+5. Choose `Commission %`.
+6. Fill in all required commission fields.
+7. Click `Save`.
+
+### Expected Result
+- The system should block the save.
+- The team should not save with the same employee listed twice.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 4: Switching Between Hourly and Commission Changes the Input Style
+### Goal
+Confirm the rate section changes correctly when the payout method changes.
+
+### Steps
+1. Open the same team again.
+2. On the team member row, change `Payout Method` from `Commission %` to `Hourly`.
+3. Look at the rate fields that appear.
+4. Change `Payout Method` back to `Commission %`.
+5. Look at the rate fields again.
+
+### Expected Result
+- In `Hourly` mode, the rate boxes should behave like money/rate fields.
+- In `Commission %` mode, the rate boxes should behave like percentage fields.
+- The screen should clearly show you are editing the correct type of value.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 5: Boundary Values for Commission %
+### Goal
+Confirm the feature accepts valid boundary values and blocks invalid ones.
+
+### Steps
+1. Open the team again.
+2. In one commission box, enter `0`.
+3. In another commission box, enter `100`.
+4. Click `Save`.
+5. Try to type a value above `100` in one of the commission boxes.
+6. Try to type a negative value in one of the commission boxes.
+
+### Expected Result
+- `0` should be accepted.
+- `100` should be accepted.
+- Values above `100` should not be allowed or should fail validation.
+- Negative values should not be allowed or should fail validation.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 6: Inactive Teams Should Not Be Offered for New Assignment
+### Goal
+Confirm inactive teams do not appear as normal team choices.
+
+### Steps
+1. Open the team again.
+2. Turn `Active` off.
+3. Click `Save`.
+4. Open a converted repair order.
+5. Go to the job lines area where the `Team` column is visible.
+6. Click inside the `Team` field on any labor line.
+7. Open the team drop-down list.
+8. Look for `Commission Team Test`.
+9. Go back to `Manage my Shop` > `Employee Teams`.
+10. Turn `Active` back on.
+11. Click `Save`.
+12. Return to the same job line and open the `Team` drop-down again.
+
+### Expected Result
+- When the team is inactive, it should not appear as a normal assignment choice.
+- After turning it back on, it should appear again.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 7: Assign the Commission Team to a Labor Line
+### Goal
+Confirm the team can be assigned to a job line from the job screen.
+
+### Steps
+1. Open a converted repair order that has labor lines.
+2. Find a labor line in the job line grid.
+3. In the `Team` column, click the blank area or the current team name.
+4. From the drop-down list, choose `Commission Team Test`.
+5. Click outside the field so it saves.
+6. Repeat for at least 1 Body line and 1 Refinish line if both exist.
+
+### Expected Result
+- The selected team name should appear in the `Team` column.
+- The assignment should stay in place after the screen refreshes.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 8: Pay All Creates Commission-Based Tickets
+### Goal
+Confirm `Pay All` creates time tickets using the commission rate, not a flat hourly rate.
+
+### Steps
+1. Use a converted repair order that has:
+2. At least 1 labor line assigned to `Commission Team Test`.
+3. Known labor sale rates on the job.
+4. No existing time tickets for the same employee and labor type.
+5. Open that repair order.
+6. Go to the labor/payroll area where the `Labor Allocations` card is visible.
+7. Write down the following before you click anything:
+8. The labor type on the line.
+9. The sold labor rate for that labor type.
+10. The hours on that line.
+11. The commission % you entered for that labor type on the team.
+12. Click `Pay All`.
+13. Wait for the success message.
+14. Look at the `Time Tickets` list on the same screen.
+15. Find the new ticket created for that employee.
+
+### Expected Result
+- The system should show `All hours paid out successfully.`
+- A new time ticket should appear.
+- The ticket rate should equal:
+- `sale rate x commission %`
+- Example: if Body sale rate is `$100.00` and commission is `40%`, the ticket rate should be `$40.00`.
+- The productive hours should match the assigned labor hours for that employee.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 9: Different Labor Types Use Different Commission Rates
+### Goal
+Confirm the feature uses the correct commission % for each labor type.
+
+### Steps
+1. Use a job that has at least:
+2. One Body labor line.
+3. One Refinish labor line.
+4. Make sure both lines are assigned to `Commission Team Test`.
+5. Confirm your team is set up like this:
+6. Body = `40%`
+7. Refinish = `30%`
+8. Open the job's `Labor Allocations` area.
+9. Click `Pay All`.
+10. Review the new time tickets that are created.
+
+### Expected Result
+- The Body ticket should use the Body commission %.
+- The Refinish ticket should use the Refinish commission %.
+- Example:
+- If Body sale rate is `$100.00`, Body payout rate should be `$40.00`.
+- If Refinish sale rate is `$120.00`, Refinish payout rate should be `$36.00`.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 10: Mixed Team With Commission and Hourly Members
+### Goal
+Confirm one team can contain both commission and hourly members, and each person is paid correctly.
+
+### Steps
+1. Open `Manage my Shop` > `Employee Teams`.
+2. Open `Commission Team Test`.
+3. Edit the first team member:
+4. Keep Employee 1 as `Commission %`.
+5. Change `Allocation %` to `60`.
+6. Make sure Body commission is still `40`.
+7. Add a second team member.
+8. Choose a different active employee.
+9. Set `Allocation %` to `40`.
+10. Set `Payout Method` to `Hourly`.
+11. Enter an hourly rate for each required labor type.
+12. For Body, use `$25.00`.
+13. Fill in the other required hourly boxes with valid values.
+14. Make sure the total allocation shows `100%`.
+15. Click `Save`.
+16. Assign this team to a Body line with `10.0` hours.
+17. Click `Pay All`.
+18. Review the new time tickets.
+
+### Expected Result
+- Employee 1 should receive `60%` of the hours at the commission-derived rate.
+- Employee 2 should receive `40%` of the hours at the hourly rate you entered.
+- Example with a 10-hour Body line and `$100.00` sale rate:
+- Employee 1 should get `6.0` hours at `$40.00`.
+- Employee 2 should get `4.0` hours at `$25.00`.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 11: Pay All Only Adds the Remaining Hours
+### Goal
+Confirm `Pay All` does not duplicate hours that were already paid.
+
+### Steps
+1. Use a job with one Body line assigned to `Commission Team Test`.
+2. Make sure the line has `10.0` hours.
+3. In the `Time Tickets` card, click `Enter New Time Ticket`.
+4. Create a manual time ticket for the same employee and the same labor type.
+5. Enter `4.0` productive hours.
+6. Save the manual time ticket.
+7. Go back to the `Labor Allocations` card.
+8. Click `Pay All`.
+9. Review the new ticket that is created.
+
+### Expected Result
+- The system should only create the remaining unpaid hours.
+- In this example, it should add `6.0` hours, not `10.0`.
+- The payout rate should still use the current commission-based rate.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 12: Unassigned Labor Lines Should Block Automatic Payout
+### Goal
+Confirm `Pay All` does not silently pay lines that do not have a team assigned.
+
+### Steps
+1. Open a converted repair order with at least 2 labor lines.
+2. Assign `Commission Team Test` to one line.
+3. Leave the second labor line with no team assigned.
+4. Go to the `Labor Allocations` card.
+5. Click `Pay All`.
+
+### Expected Result
+- The system should not quietly pay everything.
+- You should see an error telling you that not all hours have been assigned.
+- The unassigned line should still need manual attention.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Scenario 13: Flag Hours Preview Shows the Correct Payout Method
+### Goal
+If your shop uses task presets, confirm the preview shows `Commission` for commission-based tickets.
+
+### Steps
+1. Open a converted repair order.
+2. Go to the `Time Tickets` card.
+3. Click `Flag Hours`.
+4. Choose a task preset.
+5. Wait for the preview table to load.
+6. Review the `Payout Method` column in the preview.
+7. If the preview includes more than one employee, review each row.
+
+### Expected Result
+- The preview table should load without error.
+- Rows for commission-based employees should show `Commission`.
+- Rows for hourly employees should show `Hourly`.
+- If there are unassigned hours, a warning should appear.
+
+### Record
+- [ ] Pass
+- [ ] Fail
+- Notes:
+
+---
+
+## Quick Regression Checklist
+- [ ] I can create a commission-based team.
+- [ ] Allocation must total exactly 100%.
+- [ ] The same employee cannot be added twice to one team.
+- [ ] Inactive teams do not appear for normal assignment.
+- [ ] A team can be assigned to job lines from the `Team` column.
+- [ ] `Pay All` creates commission-based tickets correctly.
+- [ ] Different labor types use different commission percentages.
+- [ ] Mixed commission and hourly teams calculate correctly.
+- [ ] `Pay All` only creates the remaining unpaid hours.
+- [ ] Unassigned labor lines stop automatic payout.
+- [ ] `Flag Hours` preview shows the correct payout method.
+
+## Tester Sign-Off
+- Tester name:
+- Test date:
+- Environment:
+- Overall result:
+- Follow-up issues found:
diff --git a/client/src/components/_test/test.page.jsx b/client/src/components/_test/test.page.jsx
index 87ef90e95..a50a7d894 100644
--- a/client/src/components/_test/test.page.jsx
+++ b/client/src/components/_test/test.page.jsx
@@ -1,7 +1,11 @@
-import { Button } from "antd";
+import { Button, Card, Divider, Form, Space, Typography } from "antd";
import { connect } from "react-redux";
+import queryString from "query-string";
+import { useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { setModalContext } from "../../redux/modals/modals.actions";
+import { PayrollLaborAllocationsTable } from "../labor-allocations-table/labor-allocations-table.payroll.component.jsx";
+import { TimeTicketTaskModalComponent } from "../time-ticket-task-modal/time-ticket-task-modal.component.jsx";
const mapStateToProps = createStructuredSelector({});
@@ -9,8 +13,109 @@ const mapDispatchToProps = (dispatch) => ({
setRefundPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "refund_payment" }))
});
+const commissionCutFixture = {
+ bodyshop: {
+ features: {
+ timetickets: true
+ },
+ employees: [
+ { id: "emp-1", first_name: "Avery", last_name: "Johnson" },
+ { id: "emp-2", first_name: "Morgan", last_name: "Lee" }
+ ],
+ md_tasks_presets: {
+ presets: [
+ {
+ name: "Body Prep",
+ percent: 50,
+ hourstype: ["LAA", "LAB"],
+ nextstatus: "In Progress"
+ }
+ ]
+ }
+ },
+ jobId: "fixture-job-1",
+ joblines: [
+ {
+ id: "line-1",
+ mod_lbr_ty: "LAA",
+ mod_lb_hrs: 4,
+ assigned_team: "team-1",
+ convertedtolbr: false
+ }
+ ],
+ previewValues: {
+ task: "Body Prep",
+ timetickets: [
+ {
+ employeeid: "emp-1",
+ cost_center: "Body",
+ ciecacode: "LAA",
+ productivehrs: 2,
+ rate: 40,
+ payoutamount: 80,
+ payout_context: {
+ payout_method: "commission"
+ }
+ },
+ {
+ employeeid: "emp-2",
+ cost_center: "Refinish",
+ ciecacode: "LAB",
+ productivehrs: 1,
+ rate: 28,
+ payoutamount: 28,
+ payout_context: {
+ payout_method: "hourly"
+ }
+ }
+ ]
+ }
+};
+
+function CommissionCutHarness() {
+ const [form] = Form.useForm();
+
+ return (
+
+ Commission Cut Test Harness
+
+ This fixture keeps commission-cut browser checks stable by rendering representative payroll and preview UI with
+ local data.
+
+
+ {}}
+ />
+
+
+
+
+
+
+ );
+}
+
function Test({ setRefundPaymentContext, refundPaymentModal }) {
+ const search = queryString.parse(useLocation().search);
console.log("refundPaymentModal", refundPaymentModal);
+
+ if (search.fixture === "commission-cut") {
+ return ;
+ }
+
return (