hotfix/2026-03-12 - Be more specific on CDK error passing, resolve circular dependency

This commit is contained in:
Dave
2026-03-12 19:45:55 -04:00
parent fb863c7979
commit dd633cea89
6 changed files with 71 additions and 14 deletions

View File

@@ -46,7 +46,10 @@ const getTaskPresetAllocationErrors = (presets = [], t) => {
const laborTypeLabel = const laborTypeLabel =
translatedLaborType === `joblines.fields.lbr_types.${laborType}` ? laborType : translatedLaborType; translatedLaborType === `joblines.fields.lbr_types.${laborType}` ? laborType : translatedLaborType;
return `${laborTypeLabel} task preset total is ${total}% and cannot exceed 100%.`; return t("bodyshop.errors.task_preset_allocation_exceeded", {
laborType: laborTypeLabel,
total
});
}); });
}; };

View File

@@ -31,8 +31,8 @@ const mapDispatchToProps = () => ({});
const LABOR_TYPES = ["LAA", "LAB", "LAD", "LAE", "LAF", "LAG", "LAM", "LAR", "LAS", "LAU", "LA1", "LA2", "LA3", "LA4"]; const LABOR_TYPES = ["LAA", "LAB", "LAD", "LAE", "LAF", "LAG", "LAM", "LAR", "LAS", "LAU", "LA1", "LA2", "LA3", "LA4"];
const PAYOUT_METHOD_OPTIONS = [ const PAYOUT_METHOD_OPTIONS = [
{ label: "Hourly", value: "hourly" }, { labelKey: "employee_teams.options.hourly", value: "hourly" },
{ label: "Commission %", value: "commission" } { labelKey: "employee_teams.options.commission_percentage", value: "commission" }
]; ];
const normalizeTeamMember = (teamMember = {}) => ({ const normalizeTeamMember = (teamMember = {}) => ({
@@ -76,6 +76,10 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
const [updateEmployeeTeam] = useMutation(UPDATE_EMPLOYEE_TEAM); const [updateEmployeeTeam] = useMutation(UPDATE_EMPLOYEE_TEAM);
const [insertEmployeeTeam] = useMutation(INSERT_EMPLOYEE_TEAM); const [insertEmployeeTeam] = useMutation(INSERT_EMPLOYEE_TEAM);
const payoutMethodOptions = PAYOUT_METHOD_OPTIONS.map(({ labelKey, value }) => ({
label: t(labelKey),
value
}));
const handleFinish = async ({ employee_team_members = [], ...values }) => { const handleFinish = async ({ employee_team_members = [], ...values }) => {
const normalizedTeamMembers = employee_team_members.map((teamMember) => { const normalizedTeamMembers = employee_team_members.map((teamMember) => {
@@ -86,7 +90,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
if (normalizedTeamMembers.length === 0) { if (normalizedTeamMembers.length === 0) {
notification.error({ notification.error({
title: "Add at least one team member." title: t("employee_teams.errors.minimum_one_member")
}); });
return; return;
} }
@@ -96,14 +100,14 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
if (duplicateEmployeeIds.length > 0) { if (duplicateEmployeeIds.length > 0) {
notification.error({ notification.error({
title: "Each employee can only appear once per team." title: t("employee_teams.errors.duplicate_member")
}); });
return; return;
} }
if (!hasExactSplitTotal(normalizedTeamMembers)) { if (!hasExactSplitTotal(normalizedTeamMembers)) {
notification.error({ notification.error({
title: "Team split must total exactly 100%." title: t("employee_teams.errors.allocation_total_exact")
}); });
return; return;
} }
@@ -225,7 +229,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
<EmployeeSearchSelectComponent options={bodyshop.employees} /> <EmployeeSearchSelectComponent options={bodyshop.employees} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("employee_teams.fields.percentage")} label={t("employee_teams.fields.allocation_percentage")}
key={`${index}`} key={`${index}`}
name={[field.name, "percentage"]} name={[field.name, "percentage"]}
rules={[ rules={[
@@ -237,7 +241,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
<InputNumber min={0} max={100} precision={2} /> <InputNumber min={0} max={100} precision={2} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="Payout Method" label={t("employee_teams.fields.payout_method")}
key={`${index}-payout-method`} key={`${index}-payout-method`}
name={[field.name, "payout_method"]} name={[field.name, "payout_method"]}
initialValue="hourly" initialValue="hourly"
@@ -247,7 +251,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
} }
]} ]}
> >
<Select options={PAYOUT_METHOD_OPTIONS} /> <Select options={payoutMethodOptions} />
</Form.Item> </Form.Item>
<Form.Item noStyle dependencies={[["employee_team_members", field.name, "payout_method"]]}> <Form.Item noStyle dependencies={[["employee_team_members", field.name, "payout_method"]]}>
{() => { {() => {
@@ -309,7 +313,9 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
return ( return (
<Typography.Text type={hasExactSplitTotal(teamMembers) ? undefined : "danger"}> <Typography.Text type={hasExactSplitTotal(teamMembers) ? undefined : "danger"}>
{`Split Total: ${splitTotal.toFixed(2)}%`} {t("employee_teams.labels.allocation_total", {
total: splitTotal.toFixed(2)
})}
</Typography.Text> </Typography.Text>
); );
}} }}

View File

@@ -148,7 +148,7 @@ export function TtApprovalsListComponent({
render: (text, record) => <DateTimeFormatter>{record.clockon}</DateTimeFormatter> render: (text, record) => <DateTimeFormatter>{record.clockon}</DateTimeFormatter>
}, },
{ {
title: "Pay", title: t("timetickets.fields.pay"),
dataIndex: "pay", dataIndex: "pay",
key: "pay", key: "pay",
render: (text, record) => render: (text, record) =>

View File

@@ -305,7 +305,8 @@
"creatingdefaultview": "Error creating default view.", "creatingdefaultview": "Error creating default view.",
"duplicate_insurance_company": "Duplicate insurance company name. Each insurance company name must be unique", "duplicate_insurance_company": "Duplicate insurance company name. Each insurance company name must be unique",
"loading": "Unable to load shop details. Please call technical support.", "loading": "Unable to load shop details. Please call technical support.",
"saving": "Error encountered while saving. {{message}}" "saving": "Error encountered while saving. {{message}}",
"task_preset_allocation_exceeded": "{{laborType}} task preset total is {{total}}% and cannot exceed 100%."
}, },
"fields": { "fields": {
"ReceivableCustomField": "QBO Receivable Custom Field {{number}}", "ReceivableCustomField": "QBO Receivable Custom Field {{number}}",
@@ -1175,12 +1176,26 @@
"new": "New Team", "new": "New Team",
"newmember": "New Team Member" "newmember": "New Team Member"
}, },
"errors": {
"allocation_total_exact": "Team allocation must total exactly 100%.",
"duplicate_member": "Each employee can only appear once per team.",
"minimum_one_member": "Add at least one team member."
},
"fields": { "fields": {
"active": "Active", "active": "Active",
"allocation_percentage": "Allocation %",
"employeeid": "Employee", "employeeid": "Employee",
"max_load": "Max Load", "max_load": "Max Load",
"name": "Team Name", "name": "Team Name",
"payout_method": "Payout Method",
"percentage": "Percent" "percentage": "Percent"
},
"labels": {
"allocation_total": "Allocation Total: {{total}}%"
},
"options": {
"commission_percentage": "Commission %",
"hourly": "Hourly"
} }
}, },
"employees": { "employees": {
@@ -3608,6 +3623,7 @@
"employee_team": "Employee Team", "employee_team": "Employee Team",
"flat_rate": "Flat Rate?", "flat_rate": "Flat Rate?",
"memo": "Memo", "memo": "Memo",
"pay": "Pay",
"productivehrs": "Productive Hours", "productivehrs": "Productive Hours",
"ro_number": "Job to Post Against", "ro_number": "Job to Post Against",
"task_name": "Task" "task_name": "Task"

View File

@@ -305,7 +305,8 @@
"creatingdefaultview": "", "creatingdefaultview": "",
"duplicate_insurance_company": "", "duplicate_insurance_company": "",
"loading": "No se pueden cargar los detalles de la tienda. Por favor llame al soporte técnico.", "loading": "No se pueden cargar los detalles de la tienda. Por favor llame al soporte técnico.",
"saving": "" "saving": "",
"task_preset_allocation_exceeded": ""
}, },
"fields": { "fields": {
"ReceivableCustomField": "", "ReceivableCustomField": "",
@@ -1175,12 +1176,26 @@
"new": "", "new": "",
"newmember": "" "newmember": ""
}, },
"errors": {
"allocation_total_exact": "",
"duplicate_member": "",
"minimum_one_member": ""
},
"fields": { "fields": {
"active": "", "active": "",
"allocation_percentage": "",
"employeeid": "", "employeeid": "",
"max_load": "", "max_load": "",
"name": "", "name": "",
"payout_method": "",
"percentage": "" "percentage": ""
},
"labels": {
"allocation_total": ""
},
"options": {
"commission_percentage": "",
"hourly": ""
} }
}, },
"employees": { "employees": {
@@ -3608,6 +3623,7 @@
"employee_team": "", "employee_team": "",
"flat_rate": "", "flat_rate": "",
"memo": "", "memo": "",
"pay": "",
"productivehrs": "", "productivehrs": "",
"ro_number": "", "ro_number": "",
"task_name": "" "task_name": ""

View File

@@ -305,7 +305,8 @@
"creatingdefaultview": "", "creatingdefaultview": "",
"duplicate_insurance_company": "", "duplicate_insurance_company": "",
"loading": "Impossible de charger les détails de la boutique. Veuillez appeler le support technique.", "loading": "Impossible de charger les détails de la boutique. Veuillez appeler le support technique.",
"saving": "" "saving": "",
"task_preset_allocation_exceeded": ""
}, },
"fields": { "fields": {
"ReceivableCustomField": "", "ReceivableCustomField": "",
@@ -1175,12 +1176,26 @@
"new": "", "new": "",
"newmember": "" "newmember": ""
}, },
"errors": {
"allocation_total_exact": "",
"duplicate_member": "",
"minimum_one_member": ""
},
"fields": { "fields": {
"active": "", "active": "",
"allocation_percentage": "",
"employeeid": "", "employeeid": "",
"max_load": "", "max_load": "",
"name": "", "name": "",
"payout_method": "",
"percentage": "" "percentage": ""
},
"labels": {
"allocation_total": ""
},
"options": {
"commission_percentage": "",
"hourly": ""
} }
}, },
"employees": { "employees": {
@@ -3608,6 +3623,7 @@
"employee_team": "", "employee_team": "",
"flat_rate": "", "flat_rate": "",
"memo": "", "memo": "",
"pay": "",
"productivehrs": "", "productivehrs": "",
"ro_number": "", "ro_number": "",
"task_name": "" "task_name": ""