Merged in feature/IO-3499-React-19 (pull request #2834)

feature/IO-3499-React-19: Fix bill edit
This commit is contained in:
Dave Richer
2026-01-16 17:29:37 +00:00
2 changed files with 43 additions and 32 deletions

View File

@@ -56,7 +56,7 @@ export function BillDetailEditcontainer({ insertAuditTrail, bodyshop }) {
const handleSave = () => {
//It's got a previously deducted bill line!
if (
data.bills_by_pk.billlines.filter((b) => b.deductedfromlbr).length > 0 ||
data?.bills_by_pk?.billlines.filter((b) => b.deductedfromlbr).length > 0 ||
form.getFieldValue("billlines").filter((b) => b.deductedfromlbr).length > 0
)
setOpen(true);
@@ -84,7 +84,7 @@ export function BillDetailEditcontainer({ insertAuditTrail, bodyshop }) {
//Find bill lines that were deleted.
const deletedJobLines = [];
data.bills_by_pk.billlines.forEach((a) => {
data?.bills_by_pk?.billlines.forEach((a) => {
const matchingRecord = billlines.find((b) => b.id === a.id);
if (!matchingRecord) {
deletedJobLines.push(a);
@@ -151,8 +151,8 @@ export function BillDetailEditcontainer({ insertAuditTrail, bodyshop }) {
if (error) return <AlertComponent title={error.message} type="error" />;
if (!search.billid) return <></>; //<div>{t("bills.labels.noneselected")}</div>;
const exported = data?.bills_by_pk && data.bills_by_pk.exported;
const isinhouse = data?.bills_by_pk && data.bills_by_pk.isinhouse;
const exported = data?.bills_by_pk && data?.bills_by_pk?.exported;
const isinhouse = data?.bills_by_pk && data?.bills_by_pk?.isinhouse;
return (
<>
@@ -160,7 +160,7 @@ export function BillDetailEditcontainer({ insertAuditTrail, bodyshop }) {
{data && (
<>
<PageHeader
title={data && `${data.bills_by_pk.invoice_number} - ${data.bills_by_pk.vendor.name}`}
title={data && `${data?.bills_by_pk?.invoice_number} - ${data?.bills_by_pk?.vendor?.name}`}
extra={
<Space>
<BillDetailEditReturn data={data} />
@@ -192,15 +192,15 @@ export function BillDetailEditcontainer({ insertAuditTrail, bodyshop }) {
<Divider titlePlacement="left">{t("general.labels.media")}</Divider>
{bodyshop.uselocalmediaserver ? (
<JobsDocumentsLocalGallery
job={{ id: data ? data.bills_by_pk.jobid : null }}
invoice_number={data ? data.bills_by_pk.invoice_number : null}
vendorid={data ? data.bills_by_pk.vendorid : null}
job={{ id: data ? data?.bills_by_pk?.jobid : null }}
invoice_number={data ? data?.bills_by_pk?.invoice_number : null}
vendorid={data ? data?.bills_by_pk?.vendorid : null}
/>
) : (
<JobDocumentsGallery
jobId={data ? data.bills_by_pk.jobid : null}
jobId={data ? data?.bills_by_pk?.jobid : null}
billId={search.billid}
documentsList={data ? data.bills_by_pk.documents : []}
documentsList={data ? data?.bills_by_pk?.documents : []}
billsCallback={refetch}
/>
)}
@@ -212,7 +212,7 @@ export function BillDetailEditcontainer({ insertAuditTrail, bodyshop }) {
}
const transformData = (data) => {
return data
return data?.bills_by_pk
? {
...data.bills_by_pk,

View File

@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { selectDarkMode } from "../../redux/application/application.selectors";
import CiecaSelect from "../../utils/Ciecaselect";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
import BillLineSearchSelect from "../bill-line-search-select/bill-line-search-select.component";
@@ -14,7 +15,8 @@ import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop
bodyshop: selectBodyshop,
isDarkMode: selectDarkMode
});
const mapDispatchToProps = () => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
@@ -22,6 +24,7 @@ const mapDispatchToProps = () => ({
export function BillEnterModalLinesComponent({
bodyshop,
isDarkMode,
disabled,
lineData,
discount,
@@ -249,19 +252,26 @@ export function BillEnterModalLinesComponent({
};
},
formInput: (record, index) => (
<CurrencyInput
min={0}
disabled={disabled}
controls={false}
addonAfter={
<Form.Item shouldUpdate noStyle>
{() => {
const line = getFieldsValue(["billlines"]).billlines[index];
if (!line) return null;
let lineDiscount = 1 - line.actual_cost / line.actual_price;
if (isNaN(lineDiscount)) lineDiscount = 0;
return (
<Tooltip title={`${(lineDiscount * 100).toFixed(2) || 0}%`}>
<Space.Compact style={{ width: "100%" }}>
<CurrencyInput min={0} disabled={disabled} controls={false} style={{ width: "100%" }} />
<Form.Item shouldUpdate noStyle>
{() => {
const line = getFieldsValue(["billlines"]).billlines[index];
if (!line) return null;
let lineDiscount = 1 - line.actual_cost / line.actual_price;
if (isNaN(lineDiscount)) lineDiscount = 0;
return (
<Tooltip title={`${(lineDiscount * 100).toFixed(2) || 0}%`}>
<div
style={{
padding: "4px 11px",
display: "flex",
alignItems: "center",
background: isDarkMode ? "#141414" : "#fafafa",
border: isDarkMode ? "1px solid #424242" : "1px solid #d9d9d9",
borderLeft: 0
}}
>
<DollarCircleFilled
style={{
color:
@@ -272,12 +282,12 @@ export function BillEnterModalLinesComponent({
: "green"
}}
/>
</Tooltip>
);
}}
</Form.Item>
}
/>
</div>
</Tooltip>
);
}}
</Form.Item>
</Space.Compact>
)
// additional: (record, index) => (
// <Form.Item shouldUpdate>
@@ -627,7 +637,8 @@ const EditableCell = ({
// DO NOT mutate rawProps; omit `key` immutably
const propsFinal = rawProps
? (() => {
const { ...rest } = rawProps;
// eslint-disable-next-line no-unused-vars
const { key, ...rest } = rawProps;
return rest;
})()
: undefined;