feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Fixes to Caching of allocations summary
This commit is contained in:
@@ -24,10 +24,11 @@ export default connect(mapStateToProps, mapDispatchToProps)(DmsAllocationsSummar
|
|||||||
* @param bodyshop
|
* @param bodyshop
|
||||||
* @param jobId
|
* @param jobId
|
||||||
* @param title
|
* @param title
|
||||||
|
* @param onAllocationsChange
|
||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
export function DmsAllocationsSummary({ mode, socket, bodyshop, jobId, title }) {
|
export function DmsAllocationsSummary({ mode, socket, bodyshop, jobId, title, onAllocationsChange }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [allocationsSummary, setAllocationsSummary] = useState([]);
|
const [allocationsSummary, setAllocationsSummary] = useState([]);
|
||||||
|
|
||||||
@@ -48,11 +49,17 @@ export function DmsAllocationsSummary({ mode, socket, bodyshop, jobId, title })
|
|||||||
setAllocationsSummary(list);
|
setAllocationsSummary(list);
|
||||||
// Preserve side-channel used by the post form for discrepancy checks
|
// Preserve side-channel used by the post form for discrepancy checks
|
||||||
socket.allocationsSummary = list;
|
socket.allocationsSummary = list;
|
||||||
|
if (onAllocationsChange) onAllocationsChange(list);
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
// Best-effort; leave table empty on error
|
// Best-effort; leave table empty on error
|
||||||
setAllocationsSummary([]);
|
setAllocationsSummary([]);
|
||||||
socket && (socket.allocationsSummary = []);
|
if (socket) {
|
||||||
|
socket.allocationsSummary = [];
|
||||||
|
}
|
||||||
|
if (onAllocationsChange) {
|
||||||
|
onAllocationsChange([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [socket, jobId, mode, allocationsEvent]);
|
}, [socket, jobId, mode, allocationsEvent]);
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ function normalizeJobAllocations(ack) {
|
|||||||
* is now done on the backend via buildRogogFromAllocations/buildRolaborFromRogog.
|
* is now done on the backend via buildRogogFromAllocations/buildRolaborFromRogog.
|
||||||
* This component just renders the preview from `ack.rogg` / `ack.rolabor`.
|
* This component just renders the preview from `ack.rogg` / `ack.rolabor`.
|
||||||
*/
|
*/
|
||||||
export function RrAllocationsSummary({ socket, bodyshop, jobId, title }) {
|
export function RrAllocationsSummary({ socket, bodyshop, jobId, title, onAllocationsChange }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [roggPreview, setRoggPreview] = useState(null);
|
const [roggPreview, setRoggPreview] = useState(null);
|
||||||
const [rolaborPreview, setRolaborPreview] = useState(null);
|
const [rolaborPreview, setRolaborPreview] = useState(null);
|
||||||
@@ -70,6 +70,9 @@ export function RrAllocationsSummary({ socket, bodyshop, jobId, title }) {
|
|||||||
socket.allocationsSummary = [];
|
socket.allocationsSummary = [];
|
||||||
socket.rrAllocationsRaw = ack;
|
socket.rrAllocationsRaw = ack;
|
||||||
}
|
}
|
||||||
|
if (onAllocationsChange) {
|
||||||
|
onAllocationsChange([]);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +86,9 @@ export function RrAllocationsSummary({ socket, bodyshop, jobId, title }) {
|
|||||||
socket.allocationsSummary = jobAllocRows;
|
socket.allocationsSummary = jobAllocRows;
|
||||||
socket.rrAllocationsRaw = ack;
|
socket.rrAllocationsRaw = ack;
|
||||||
}
|
}
|
||||||
|
if (onAllocationsChange) {
|
||||||
|
onAllocationsChange(jobAllocRows);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
setRoggPreview(null);
|
setRoggPreview(null);
|
||||||
@@ -91,8 +97,11 @@ export function RrAllocationsSummary({ socket, bodyshop, jobId, title }) {
|
|||||||
if (socket) {
|
if (socket) {
|
||||||
socket.allocationsSummary = [];
|
socket.allocationsSummary = [];
|
||||||
}
|
}
|
||||||
|
if (onAllocationsChange) {
|
||||||
|
onAllocationsChange([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [socket, jobId, t]);
|
}, [socket, jobId, t, onAllocationsChange]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchAllocations();
|
fetchAllocations();
|
||||||
|
|||||||
@@ -39,10 +39,11 @@ import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
|||||||
* @param job
|
* @param job
|
||||||
* @param logsRef
|
* @param logsRef
|
||||||
* @param mode
|
* @param mode
|
||||||
|
* @param allocationsSummary
|
||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode }) {
|
export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode, allocationsSummary }) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [, /*unused*/ setTick] = useState(0); // handy if you need a forceUpdate later
|
const [, /*unused*/ setTick] = useState(0); // handy if you need a forceUpdate later
|
||||||
@@ -120,15 +121,19 @@ export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode }
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Totals & discrepancy
|
// Totals & discrepancy
|
||||||
const totals = socket?.allocationsSummary
|
const totals = useMemo(() => {
|
||||||
? socket.allocationsSummary.reduce(
|
if (!allocationsSummary || allocationsSummary.length === 0) {
|
||||||
(acc, val) => ({
|
return { totalSale: Dinero(), totalCost: Dinero() };
|
||||||
totalSale: acc.totalSale.add(Dinero(val.sale)),
|
}
|
||||||
totalCost: acc.totalCost.add(Dinero(val.cost))
|
|
||||||
}),
|
return allocationsSummary.reduce(
|
||||||
{ totalSale: Dinero(), totalCost: Dinero() }
|
(acc, val) => ({
|
||||||
)
|
totalSale: acc.totalSale.add(Dinero(val.sale)),
|
||||||
: { totalSale: Dinero(), totalCost: Dinero() };
|
totalCost: acc.totalCost.add(Dinero(val.cost))
|
||||||
|
}),
|
||||||
|
{ totalSale: Dinero(), totalCost: Dinero() }
|
||||||
|
);
|
||||||
|
}, [allocationsSummary]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card title={t("jobs.labels.dms.postingform")}>
|
<Card title={t("jobs.labels.dms.postingform")}>
|
||||||
@@ -214,7 +219,7 @@ export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode }
|
|||||||
<Row gutter={[16, 12]}>
|
<Row gutter={[16, 12]}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<Form.Item name="story" label={t("jobs.fields.dms.story")} rules={[{ required: true }]}>
|
<Form.Item name="story" label={t("jobs.fields.dms.story")} rules={[{ required: true }]}>
|
||||||
<Input.TextArea maxLength={Fortellis.treatment === "on" ? 40 : 240} showCount/>
|
<Input.TextArea maxLength={Fortellis.treatment === "on" ? 40 : 240} showCount />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
@@ -382,7 +387,10 @@ export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode }
|
|||||||
const payersOk =
|
const payersOk =
|
||||||
payers.length > 0 &&
|
payers.length > 0 &&
|
||||||
payers.every((p) => p?.name && p.dms_acctnumber && (p.amount ?? "") !== "" && p.controlnumber);
|
payers.every((p) => p?.name && p.dms_acctnumber && (p.amount ?? "") !== "" && p.controlnumber);
|
||||||
const nonRrDiscrepancyGate = socket?.allocationsSummary ? discrep.getAmount() !== 0 : true;
|
|
||||||
|
const hasAllocations = allocationsSummary && allocationsSummary.length > 0;
|
||||||
|
const nonRrDiscrepancyGate = hasAllocations ? discrep.getAmount() !== 0 : true;
|
||||||
|
|
||||||
const disablePost = !payersOk || nonRrDiscrepancyGate;
|
const disablePost = !payersOk || nonRrDiscrepancyGate;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -19,20 +19,41 @@ export default connect(mapStateToProps, mapDispatchToProps)(DmsPostForm);
|
|||||||
* @param socket
|
* @param socket
|
||||||
* @param job
|
* @param job
|
||||||
* @param logsRef
|
* @param logsRef
|
||||||
|
* @param key
|
||||||
|
* @param allocationsSummary
|
||||||
* @returns {JSX.Element|null}
|
* @returns {JSX.Element|null}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
export function DmsPostForm({ mode, bodyshop, socket, job, logsRef }) {
|
export function DmsPostForm({ mode, bodyshop, socket, job, logsRef, key, allocationsSummary }) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DMS_MAP.reynolds:
|
case DMS_MAP.reynolds:
|
||||||
return <RRPostForm bodyshop={bodyshop} socket={socket} job={job} logsRef={logsRef} />;
|
return (
|
||||||
|
<RRPostForm
|
||||||
|
bodyshop={bodyshop}
|
||||||
|
socket={socket}
|
||||||
|
job={job}
|
||||||
|
logsRef={logsRef}
|
||||||
|
key={key}
|
||||||
|
allocationsSummary={allocationsSummary}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
// CDK (legacy /ws), Fortellis (CDK-over-WSS), and PBS share the same UI;
|
// CDK (legacy /ws), Fortellis (CDK-over-WSS), and PBS share the same UI;
|
||||||
// we pass mode down so the child can choose the correct event name.
|
// we pass mode down so the child can choose the correct event name.
|
||||||
case DMS_MAP.fortellis:
|
case DMS_MAP.fortellis:
|
||||||
case DMS_MAP.cdk:
|
case DMS_MAP.cdk:
|
||||||
case DMS_MAP.pbs:
|
case DMS_MAP.pbs:
|
||||||
return <CdkLikePostForm mode={mode} bodyshop={bodyshop} socket={socket} job={job} logsRef={logsRef} />;
|
return (
|
||||||
|
<CdkLikePostForm
|
||||||
|
mode={mode}
|
||||||
|
bodyshop={bodyshop}
|
||||||
|
socket={socket}
|
||||||
|
job={job}
|
||||||
|
logsRef={logsRef}
|
||||||
|
key={key}
|
||||||
|
allocationsSummary={allocationsSummary}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -26,10 +26,11 @@ import dayjs from "../../utils/day";
|
|||||||
* @param socket
|
* @param socket
|
||||||
* @param job
|
* @param job
|
||||||
* @param logsRef
|
* @param logsRef
|
||||||
|
* @param allocationsSummary
|
||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
export default function RRPostForm({ bodyshop, socket, job, logsRef }) {
|
export default function RRPostForm({ bodyshop, socket, job, logsRef, allocationsSummary }) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -113,16 +114,21 @@ export default function RRPostForm({ bodyshop, socket, job, logsRef }) {
|
|||||||
logsRef?.current?.scrollIntoView({ behavior: "smooth" });
|
logsRef?.current?.scrollIntoView({ behavior: "smooth" });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Discrepancy is ignored for RR; we still show totals for operator context
|
// Discrepancy is ignored for RR; we still show totals for operator context.
|
||||||
const totals = socket?.allocationsSummary
|
// Use the lifted allocationsSummary from the container instead of reading from the socket.
|
||||||
? socket.allocationsSummary.reduce(
|
const totals = useMemo(() => {
|
||||||
(acc, val) => ({
|
if (!allocationsSummary || allocationsSummary.length === 0) {
|
||||||
totalSale: acc.totalSale.add(Dinero(val.sale)),
|
return { totalSale: Dinero(), totalCost: Dinero() };
|
||||||
totalCost: acc.totalCost.add(Dinero(val.cost))
|
}
|
||||||
}),
|
|
||||||
{ totalSale: Dinero(), totalCost: Dinero() }
|
return allocationsSummary.reduce(
|
||||||
)
|
(acc, val) => ({
|
||||||
: { totalSale: Dinero(), totalCost: Dinero() };
|
totalSale: acc.totalSale.add(Dinero(val.sale)),
|
||||||
|
totalCost: acc.totalCost.add(Dinero(val.cost))
|
||||||
|
}),
|
||||||
|
{ totalSale: Dinero(), totalCost: Dinero() }
|
||||||
|
);
|
||||||
|
}, [allocationsSummary]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card title={t("jobs.labels.dms.postingform")}>
|
<Card title={t("jobs.labels.dms.postingform")}>
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ const DMS_SOCKET_EVENTS = {
|
|||||||
export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, insertAuditTrail }) {
|
export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, insertAuditTrail }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [resetAfterReconnect, setResetAfterReconnect] = useState(false);
|
const [resetAfterReconnect, setResetAfterReconnect] = useState(false);
|
||||||
|
const [allocationsSummary, setAllocationsSummary] = useState(null);
|
||||||
|
|
||||||
const history = useNavigate();
|
const history = useNavigate();
|
||||||
const search = queryString.parse(useLocation().search);
|
const search = queryString.parse(useLocation().search);
|
||||||
@@ -152,6 +153,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
|||||||
setLogs([]);
|
setLogs([]);
|
||||||
setRrOpenRoLimit(false);
|
setRrOpenRoLimit(false);
|
||||||
setrrValidationPending(false);
|
setrrValidationPending(false);
|
||||||
|
setAllocationsSummary(null);
|
||||||
|
|
||||||
if (!activeSocket) return;
|
if (!activeSocket) return;
|
||||||
|
|
||||||
@@ -398,6 +400,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
|||||||
{!isRrMode ? (
|
{!isRrMode ? (
|
||||||
<DmsAllocationsSummary
|
<DmsAllocationsSummary
|
||||||
key={resetKey}
|
key={resetKey}
|
||||||
|
onAllocationsChange={setAllocationsSummary}
|
||||||
title={
|
title={
|
||||||
<span>
|
<span>
|
||||||
<Link
|
<Link
|
||||||
@@ -415,6 +418,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
|||||||
) : (
|
) : (
|
||||||
<RrAllocationsSummary
|
<RrAllocationsSummary
|
||||||
key={resetKey}
|
key={resetKey}
|
||||||
|
onAllocationsChange={setAllocationsSummary}
|
||||||
title={
|
title={
|
||||||
<span>
|
<span>
|
||||||
<Link to={`/manage/jobs/${data && data.jobs_by_pk.id}`}>
|
<Link to={`/manage/jobs/${data && data.jobs_by_pk.id}`}>
|
||||||
@@ -432,7 +436,14 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
|||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<Col md={24} lg={14} className="dms-equal-height-col">
|
<Col md={24} lg={14} className="dms-equal-height-col">
|
||||||
<DmsPostForm key={resetKey} socket={activeSocket} job={data?.jobs_by_pk} logsRef={logsRef} mode={mode} />
|
<DmsPostForm
|
||||||
|
key={resetKey}
|
||||||
|
socket={activeSocket}
|
||||||
|
job={data?.jobs_by_pk}
|
||||||
|
logsRef={logsRef}
|
||||||
|
mode={mode}
|
||||||
|
allocationsSummary={allocationsSummary}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<DmsCustomerSelector
|
<DmsCustomerSelector
|
||||||
|
|||||||
Reference in New Issue
Block a user