Compare commits

..

2 Commits

Author SHA1 Message Date
Dave
217a0b84ac bugfix/IO-3533 - Fix 2026-02-02 17:04:06 -05:00
Dave
45e143578c bugfix/IO-3533 - Disable on blurr and on focus handlers in bill entry modal 2026-02-02 12:34:54 -05:00
4 changed files with 32 additions and 17 deletions

View File

@@ -90,6 +90,7 @@ export function BillEnterModalLinesComponent({
}); });
}; };
// Only fill actual_cost when the user forward-tabs out of Retail (actual_price)
const autofillActualCost = (index) => { const autofillActualCost = (index) => {
Promise.resolve().then(() => { Promise.resolve().then(() => {
const retailRaw = form.getFieldValue(["billlines", index, "actual_price"]); const retailRaw = form.getFieldValue(["billlines", index, "actual_price"]);
@@ -164,10 +165,9 @@ export function BillEnterModalLinesComponent({
}} }}
allowRemoved={form.getFieldValue("is_credit_memo") || false} allowRemoved={form.getFieldValue("is_credit_memo") || false}
onSelect={(value, opt) => { onSelect={(value, opt) => {
const d = normalizeDiscount(discount); // IMPORTANT:
const retail = Number(opt.cost); // Do NOT autofill actual_cost here. It should only fill when the user forward-tabs
const computedActual = Number.isFinite(retail) ? round2(retail * (1 - d)) : null; // from Retail (actual_price) -> Actual Cost (actual_cost).
setFieldsValue({ setFieldsValue({
billlines: (getFieldValue("billlines") || []).map((item, idx) => { billlines: (getFieldValue("billlines") || []).map((item, idx) => {
if (idx !== index) return item; if (idx !== index) return item;
@@ -178,7 +178,7 @@ export function BillEnterModalLinesComponent({
quantity: opt.part_qty || 1, quantity: opt.part_qty || 1,
actual_price: opt.cost, actual_price: opt.cost,
original_actual_price: opt.cost, original_actual_price: opt.cost,
actual_cost: isBlank(item.actual_cost) ? computedActual : item.actual_cost, // actual_cost intentionally untouched here
cost_center: opt.part_type cost_center: opt.part_type
? bodyshopHasDmsKey(bodyshop) ? bodyshopHasDmsKey(bodyshop)
? opt.part_type !== "PAE" ? opt.part_type !== "PAE"
@@ -251,9 +251,9 @@ export function BillEnterModalLinesComponent({
<CurrencyInput <CurrencyInput
min={0} min={0}
disabled={disabled} disabled={disabled}
onBlur={() => autofillActualCost(index)} // NOTE: Autofill should only happen on forward Tab out of Retail
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === "Tab") autofillActualCost(index); if (e.key === "Tab" && !e.shiftKey) autofillActualCost(index);
}} }}
/> />
), ),
@@ -329,7 +329,7 @@ export function BillEnterModalLinesComponent({
disabled={disabled} disabled={disabled}
controls={false} controls={false}
style={{ width: "100%", height: CONTROL_HEIGHT }} style={{ width: "100%", height: CONTROL_HEIGHT }}
onFocus={() => autofillActualCost(index)} // NOTE: No auto-fill on focus/blur; only triggered from Retail on Tab
/> />
</Form.Item> </Form.Item>
</div> </div>

View File

@@ -81,17 +81,16 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is
const employeeData = bodyshop.associations.find((a) => a.useremail === job.admin_clerk)?.user?.employee ?? null; const employeeData = bodyshop.associations.find((a) => a.useremail === job.admin_clerk)?.user?.employee ?? null;
// Handle checkbox changes // Handle checkbox changes
const handleCheckboxChange = async (field, e) => { const handleCheckboxChange = async (field, checked) => {
e.preventDefault();
e.stopPropagation();
const checked = e.target.checked;
const value = checked ? dayjs().toISOString() : null; const value = checked ? dayjs().toISOString() : null;
try { try {
const ret = await updateJob({ const ret = await updateJob({
variables: { variables: {
jobId: job.id, jobId: job.id,
job: { [field]: value } job: { [field]: value }
} },
refetchQueries: ["GET_JOB_BY_PK"],
awaitRefetchQueries: true
}); });
insertAuditTrail({ insertAuditTrail({
jobid: job.id, jobid: job.id,
@@ -183,7 +182,7 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is
<Space> <Space>
<Checkbox <Checkbox
checked={!!job.estimate_sent_approval} checked={!!job.estimate_sent_approval}
onChange={(e) => handleCheckboxChange("estimate_sent_approval", e)} onChange={(e) => handleCheckboxChange("estimate_sent_approval", e.target.checked)}
disabled={disabled || isPartsEntry} disabled={disabled || isPartsEntry}
> >
{job.estimate_sent_approval && ( {job.estimate_sent_approval && (
@@ -198,7 +197,7 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is
<Space> <Space>
<Checkbox <Checkbox
checked={!!job.estimate_approved} checked={!!job.estimate_approved}
onChange={(e) => handleCheckboxChange("estimate_approved", e)} onChange={(e) => handleCheckboxChange("estimate_approved", e.target.checked)}
disabled={disabled || isPartsEntry} disabled={disabled || isPartsEntry}
> >
{job.estimate_approved && ( {job.estimate_approved && (

View File

@@ -33,7 +33,8 @@ export function TaskListContainer({
currentUser, currentUser,
onlyMine, onlyMine,
parentJobId, parentJobId,
showRo = true showRo = true,
disableJobRefetch = false
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const notification = useNotification(); const notification = useNotification();
@@ -90,6 +91,10 @@ export function TaskListContainer({
refetchQueries: [Object.keys(query)[0]] refetchQueries: [Object.keys(query)[0]]
}; };
if (!disableJobRefetch) {
toggledTaskObject.refetchQueries.push("GET_JOB_BY_PK");
}
const toggledTask = await toggleTaskCompleted(toggledTaskObject); const toggledTask = await toggleTaskCompleted(toggledTaskObject);
if (!toggledTask.errors) { if (!toggledTask.errors) {
@@ -139,6 +144,10 @@ export function TaskListContainer({
refetchQueries: [Object.keys(query)[0]] refetchQueries: [Object.keys(query)[0]]
}; };
if (!disableJobRefetch) {
toggledTaskObject.refetchQueries.push("GET_JOB_BY_PK");
}
const toggledTask = await toggleTaskDeleted(toggledTaskObject); const toggledTask = await toggleTaskDeleted(toggledTaskObject);
if (!toggledTask.errors) { if (!toggledTask.errors) {

View File

@@ -23,10 +23,17 @@ export function TasksPageComponent({ bodyshop, currentUser, type }) {
relationshipType={"assigned_to"} relationshipType={"assigned_to"}
query={{ QUERY_MY_TASKS_PAGINATED }} query={{ QUERY_MY_TASKS_PAGINATED }}
titleTranslation={"tasks.titles.my_tasks"} titleTranslation={"tasks.titles.my_tasks"}
disableJobRefetch={true}
/> />
); );
case taskPageTypes.ALL_TASKS: case taskPageTypes.ALL_TASKS:
return <TaskListContainer query={{ QUERY_ALL_TASKS_PAGINATED }} titleTranslation={"tasks.titles.all_tasks"} />; return (
<TaskListContainer
query={{ QUERY_ALL_TASKS_PAGINATED }}
titleTranslation={"tasks.titles.all_tasks"}
disableJobRefetch={true}
/>
);
default: default:
return <></>; return <></>;
} }