Compare commits

..

1 Commits

Author SHA1 Message Date
Allan Carr
a5f7ff3089 IO-3491 QBO SALESTERMSREF
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-12-31 09:25:12 -08:00
41 changed files with 83 additions and 287 deletions

View File

@@ -19,35 +19,30 @@ const mapDispatchToProps = (dispatch) => ({
openChatByPhone: (phone) => dispatch(openChatByPhone(phone))
});
export function ChatOpenButton({ bodyshop, searchingForConversation, phone, type, jobid, openChatByPhone }) {
export function ChatOpenButton({ bodyshop, searchingForConversation, phone, jobid, openChatByPhone }) {
const { t } = useTranslation();
const { socket } = useSocket();
const notification = useNotification();
if (!phone) return <></>;
if (!bodyshop.messagingservicesid) {
return <PhoneNumberFormatter type={type}>{phone}</PhoneNumberFormatter>;
}
if (!bodyshop.messagingservicesid) return <PhoneNumberFormatter>{phone}</PhoneNumberFormatter>;
return (
<a
href="# "
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (searchingForConversation) return; // Prevent finding the same thing twice.
const p = parsePhoneNumber(phone, "CA");
if (searchingForConversation) return; //This is to prevent finding the same thing twice.
if (p && p.isValid()) {
openChatByPhone({ phone_num: p.formatInternational(), jobid, socket });
openChatByPhone({ phone_num: p.formatInternational(), jobid: jobid, socket });
} else {
notification["error"]({ message: t("messaging.error.invalidphone") });
}
}}
>
<PhoneNumberFormatter type={type}>{phone}</PhoneNumberFormatter>
<PhoneNumberFormatter>{phone}</PhoneNumberFormatter>
</a>
);
}

View File

@@ -133,9 +133,6 @@ export function ContractConvertToRo({ bodyshop, currentUser, contract, disabled
ownr_ln: contract.job.owner.ownr_ln,
ownr_co_nm: contract.job.owner.ownr_co_nm,
ownr_ph1: contract.job.owner.ownr_ph1,
ownr_ph2: contract.job.owner.ownr_ph2,
ownr_ph1_ty: contract.job.owner.ownr_ph1_ty,
ownr_ph2_ty: contract.job.owner.ownr_ph2_ty,
ownr_ea: contract.job.owner.ownr_ea,
v_model_desc: contract.job.vehicle && contract.job.vehicle.v_model_desc,
v_model_yr: contract.job.vehicle && contract.job.vehicle.v_model_yr,

View File

@@ -256,9 +256,9 @@ export default function DashboardScheduledDeliveryToday({ data, ...cardProps })
responsive: ["md"],
render: (text, record) => (
<Space size="small" wrap>
<ChatOpenButton type={record.ownr_ph1_ty} phone={record.ownr_ph1} jobid={record.jobid} />
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid} />
<ChatOpenButton type={record.ownr_ph2_ty} phone={record.ownr_ph2} jobid={record.jobid} />
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid} />
</Space>
)
},
@@ -397,8 +397,6 @@ export const DashboardScheduledDeliveryTodayGql = `
ownr_ln
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
production_vars
ro_number
scheduled_delivery

View File

@@ -48,8 +48,6 @@ export default function DashboardScheduledInToday({ data, ...cardProps }) {
ownr_ln: item.job.ownr_ln,
ownr_ph1: item.job.ownr_ph1,
ownr_ph2: item.job.ownr_ph2,
ownr_ph1_ty: item.job.ownr_ph1_ty,
ownr_ph2_ty: item.job.ownr_ph2_ty,
production_vars: item.job.production_vars,
ro_number: item.job.ro_number,
suspended: item.job.suspended,
@@ -266,8 +264,8 @@ export default function DashboardScheduledInToday({ data, ...cardProps }) {
responsive: ["md"],
render: (text, record) => (
<Space size="small" wrap>
<ChatOpenButton type={record.ownr_ph1_ty} phone={record.ownr_ph1} jobid={record.jobid} />
<ChatOpenButton type={record.ownr_ph2_ty} phone={record.ownr_ph2} jobid={record.jobid} />
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid} />
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid} />
</Space>
)
},
@@ -402,8 +400,6 @@ export const DashboardScheduledInTodayGql = `
ownr_ln
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
production_vars
ro_number
suspended

View File

@@ -256,9 +256,9 @@ export default function DashboardScheduledOutToday({ data, ...cardProps }) {
responsive: ["md"],
render: (text, record) => (
<Space size="small" wrap>
<ChatOpenButton type={record.ownr_ph1_ty} phone={record.ownr_ph1} jobid={record.jobid} />
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid} />
<ChatOpenButton type={record.ownr_ph2_ty} phone={record.ownr_ph2} jobid={record.jobid} />
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid} />
</Space>
)
},
@@ -397,8 +397,6 @@ export const DashboardScheduledOutTodayGql = `
ownr_ln
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
production_vars
ro_number
scheduled_completion

View File

@@ -73,8 +73,8 @@ export default function GlobalSearchOs() {
<span>
<OwnerNameDisplay ownerObject={owner} />
</span>
<PhoneNumberFormatter type={owner?.ownr_ph1_ty}>{owner.ownr_ph1}</PhoneNumberFormatter>
<PhoneNumberFormatter type={owner?.ownr_ph2_ty}>{owner.ownr_ph2}</PhoneNumberFormatter>
<PhoneNumberFormatter>{owner.ownr_ph1}</PhoneNumberFormatter>
<PhoneNumberFormatter>{owner.ownr_ph2}</PhoneNumberFormatter>
</Space>
</Link>
)

View File

@@ -63,8 +63,8 @@ export default function GlobalSearch() {
<span>
<OwnerNameDisplay ownerObject={owner} />
</span>
<PhoneNumberFormatter type={owner.ownr_ph1_ty}>{owner.ownr_ph1}</PhoneNumberFormatter>
<PhoneNumberFormatter type={owner.ownr_ph2_ty}>{owner.ownr_ph2}</PhoneNumberFormatter>
<PhoneNumberFormatter>{owner.ownr_ph1}</PhoneNumberFormatter>
<PhoneNumberFormatter>{owner.ownr_ph2}</PhoneNumberFormatter>
</Space>
</Link>
)

View File

@@ -220,10 +220,10 @@ export function ScheduleEventComponent({
</DataLabel>
<DataLabel label={t("jobs.fields.ownr_ea")}>{(event.job && event.job.ownr_ea) || ""}</DataLabel>
<DataLabel label={t("jobs.fields.ownr_ph1")}>
<ChatOpenButton phone={event?.job?.ownr_ph1} type={event?.job?.ownr_ph1_ty} jobid={event.job.id} />
<ChatOpenButton phone={event.job && event.job.ownr_ph1} jobid={event.job.id} />
</DataLabel>
<DataLabel label={t("jobs.fields.ownr_ph2")}>
<ChatOpenButton phone={event?.job?.ownr_ph2} type={event?.job?.ownr_ph2_ty} jobid={event.job.id} />
<ChatOpenButton phone={event.job && event.job.ownr_ph2} jobid={event.job.id} />
</DataLabel>
<DataLabel hideIfNull label={t("jobs.fields.loss_of_use")}>
{(event.job && event.job.loss_of_use) || ""}

View File

@@ -1,4 +1,4 @@
import { Form, Input, Select } from "antd";
import { Form, Input } from "antd";
import { useContext } from "react";
import { useTranslation } from "react-i18next";
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
@@ -7,11 +7,6 @@ import FormItemPhone, { PhoneItemFormatterValidation } from "../form-items-forma
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function JobsCreateOwnerInfoNewComponent() {
const PHONE_TYPE_OPTIONS = [
{ label: t("owners.labels.home"), value: "Home" },
{ label: t("owners.labels.work"), value: "Work" },
{ label: t("owners.labels.cell"), value: "Cell" }
];
const [state] = useContext(JobCreateContext);
const { t } = useTranslation();
@@ -110,56 +105,26 @@ export default function JobsCreateOwnerInfoNewComponent() {
]}
name={["owner", "data", "ownr_ea"]}
>
<FormItemEmail disabled={!state.owner.new} />
<FormItemEmail
//email={form.getFieldValue("ownr_ea")}
disabled={!state.owner.new}
/>
</Form.Item>
{/* Phone 1 + Type */}
<Form.Item label={t("owners.fields.ownr_ph1")} style={{ marginBottom: 0 }}>
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<Form.Item
name={["owner", "data", "ownr_ph1"]}
noStyle
rules={[({ getFieldValue }) => PhoneItemFormatterValidation(getFieldValue, "owner.data.ownr_ph1")]}
>
<FormItemPhone disabled={!state.owner.new} style={{ flex: 1, minWidth: 150 }} />
</Form.Item>
<Form.Item name={["owner", "data", "ownr_ph1_ty"]} noStyle>
<Select
disabled={!state.owner.new}
allowClear
placeholder="Type"
options={PHONE_TYPE_OPTIONS}
style={{ width: 110 }}
/>
</Form.Item>
</div>
<Form.Item
label={t("owners.fields.ownr_ph1")}
name={["owner", "data", "ownr_ph1"]}
rules={[({ getFieldValue }) => PhoneItemFormatterValidation(getFieldValue, "owner.data.ownr_ph1")]}
>
<FormItemPhone disabled={!state.owner.new} />
</Form.Item>
{/* Phone 2 + Type */}
<Form.Item label={t("owners.fields.ownr_ph2")} style={{ marginBottom: 0 }}>
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<Form.Item
name={["owner", "data", "ownr_ph2"]}
noStyle
rules={[({ getFieldValue }) => PhoneItemFormatterValidation(getFieldValue, "owner.data.ownr_ph2")]}
>
<FormItemPhone disabled={!state.owner.new} style={{ flex: 1, minWidth: 150 }} />
</Form.Item>
<Form.Item name={["owner", "data", "ownr_ph2_ty"]} noStyle>
<Select
disabled={!state.owner.new}
allowClear
placeholder="Type"
options={PHONE_TYPE_OPTIONS}
style={{ width: 110 }}
/>
</Form.Item>
</div>
<Form.Item
label={t("owners.fields.ownr_ph2")}
name={["owner", "data", "ownr_ph2"]}
rules={[({ getFieldValue }) => PhoneItemFormatterValidation(getFieldValue, "owner.data.ownr_ph2")]}
>
<FormItemPhone disabled={!state.owner.new} />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
<Form.Item label={t("owners.fields.preferred_contact")} name={["owner", "data", "preferred_contact"]}>
<Input disabled={!state.owner.new} />

View File

@@ -61,7 +61,7 @@ export default function JobsCreateOwnerInfoSearchComponent({ loading, owners })
title: t("owners.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
render: (text, record) => <PhoneFormatter type={record.ownr_ph1_ty}>{record.ownr_ph1}</PhoneFormatter>,
render: (text, record) => <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>,
sorter: (a, b) => alphaSort(a.ownr_ph1, b.ownr_ph1),
sortOrder: tableState.sortedInfo.columnKey === "ownr_ph1" && tableState.sortedInfo.order
},
@@ -69,7 +69,7 @@ export default function JobsCreateOwnerInfoSearchComponent({ loading, owners })
title: t("owners.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
render: (text, record) => <PhoneFormatter type={record.ownr_ph2_ty}>{record.ownr_ph2}</PhoneFormatter>,
render: (text, record) => <PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>,
sorter: (a, b) => alphaSort(a.ownr_ph2, b.ownr_ph2),
sortOrder: tableState.sortedInfo.columnKey === "ownr_ph2" && tableState.sortedInfo.order
}

View File

@@ -251,16 +251,16 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, is
<div>
<DataLabel key="2" label={t("jobs.fields.ownr_ph1")}>
{disabled || isPartsEntry ? (
<PhoneNumberFormatter type={job.ownr_ph1_ty}>{job.ownr_ph1}</PhoneNumberFormatter>
<PhoneNumberFormatter>{job.ownr_ph1}</PhoneNumberFormatter>
) : (
<ChatOpenButton type={job.ownr_ph1_ty} phone={job.ownr_ph1} jobid={job.id} />
<ChatOpenButton phone={job.ownr_ph1} jobid={job.id} />
)}
</DataLabel>
<DataLabel key="22" label={t("jobs.fields.ownr_ph2")}>
{disabled || isPartsEntry ? (
<PhoneNumberFormatter type={job.ownr_ph2_ty}>{job.ownr_ph2}</PhoneNumberFormatter>
<PhoneNumberFormatter>{job.ownr_ph2}</PhoneNumberFormatter>
) : (
<ChatOpenButton type={job.ownr_ph2_ty} phone={job.ownr_ph2} jobid={job.id} />
<ChatOpenButton phone={job.ownr_ph2} jobid={job.id} />
)}
</DataLabel>
<DataLabel key="3" label={t("owners.fields.address")}>

View File

@@ -64,11 +64,7 @@ export default function JobsFindModalComponent({
width: "12%",
ellipsis: true,
render: (text, record) => {
return record.ownr_ph1 ? (
<PhoneFormatter type={record.ownr_ph1_ty}>{record.ownr_ph1}</PhoneFormatter>
) : (
t("general.labels.unknown")
);
return record.ownr_ph1 ? <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter> : t("general.labels.unknown");
}
},
{
@@ -78,11 +74,7 @@ export default function JobsFindModalComponent({
width: "12%",
ellipsis: true,
render: (text, record) => {
return record.ownr_ph2 ? (
<PhoneFormatter type={record.ownr_ph2_ty}>{record.ownr_ph2}</PhoneFormatter>
) : (
t("general.labels.unknown")
);
return record.ownr_ph2 ? <PhoneFormatter>{record.ownr_ph2}</PhoneFormatter> : t("general.labels.unknown");
}
},
{
@@ -253,11 +245,7 @@ export default function JobsFindModalComponent({
>
{t("jobs.labels.override_header")}
</Checkbox>
<Checkbox
checked={partsQueueToggle}
onChange={(e) => setPartsQueueToggle(e.target.checked)}
id="parts_queue_toggle"
>
<Checkbox checked={partsQueueToggle} onChange={(e) => setPartsQueueToggle(e.target.checked)} id="parts_queue_toggle">
{t("bodyshop.fields.md_functionality_toggles.parts_queue_toggle")}
</Checkbox>
<Checkbox

View File

@@ -72,14 +72,14 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
dataIndex: "ownr_ph1",
key: "ownr_ph1",
ellipsis: true,
render: (text, record) => <StartChatButton type={record.ownr_ph1_ty} phone={record.ownr_ph1} jobid={record.id} />
render: (text, record) => <StartChatButton phone={record.ownr_ph1} jobid={record.id} />
},
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
render: (text, record) => <StartChatButton type={record.ownr_ph2_ty} phone={record.ownr_ph2} jobid={record.id} />
render: (text, record) => <StartChatButton phone={record.ownr_ph2} jobid={record.id} />
},
{
title: t("jobs.fields.status"),

View File

@@ -139,7 +139,7 @@ export function JobsList({ bodyshop }) {
key: "ownr_ph1",
ellipsis: true,
responsive: ["md"],
render: (text, record) => <ChatOpenButton type={record.ownr_ph1_ty} phone={record.ownr_ph1} jobid={record.id} />
render: (text, record) => <ChatOpenButton phone={record.ownr_ph1} jobid={record.id} />
},
{
title: t("jobs.fields.ownr_ph2"),
@@ -147,7 +147,7 @@ export function JobsList({ bodyshop }) {
key: "ownr_ph2",
ellipsis: true,
responsive: ["md"],
render: (text, record) => <ChatOpenButton type={record.ownr_ph2_ty} phone={record.ownr_ph2} jobid={record.id} />
render: (text, record) => <ChatOpenButton phone={record.ownr_ph2} jobid={record.id} />
},
{

View File

@@ -140,7 +140,7 @@ export function JobsReadyList({ bodyshop }) {
key: "ownr_ph1",
ellipsis: true,
responsive: ["md"],
render: (text, record) => <ChatOpenButton type={record.ownr_ph1_ty} phone={record.ownr_ph1} jobid={record.id} />
render: (text, record) => <ChatOpenButton phone={record.ownr_ph1} jobid={record.id} />
},
{
title: t("jobs.fields.ownr_ph2"),
@@ -148,7 +148,7 @@ export function JobsReadyList({ bodyshop }) {
key: "ownr_ph2",
ellipsis: true,
responsive: ["md"],
render: (text, record) => <ChatOpenButton type={record.ownr_ph2_ty} phone={record.ownr_ph2} jobid={record.id} />
render: (text, record) => <ChatOpenButton phone={record.ownr_ph2} jobid={record.id} />
},
{
title: t("jobs.fields.status"),

View File

@@ -1,4 +1,4 @@
import { Form, Input, Select, Tooltip } from "antd";
import { Form, Input, Tooltip } from "antd";
import { CloseCircleFilled } from "@ant-design/icons";
import { useTranslation } from "react-i18next";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
@@ -10,12 +10,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
const { t } = useTranslation();
const { getFieldValue } = form;
const PHONE_TYPE_OPTIONS = [
{ label: t("owners.labels.home"), value: "Home" },
{ label: t("owners.labels.work"), value: "Work" },
{ label: t("owners.labels.cell"), value: "Cell" }
];
return (
<div>
<FormFieldsChanged form={form} />
@@ -36,7 +30,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
<Input disabled />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow header={t("owners.forms.address")}>
<Form.Item label={t("owners.fields.ownr_addr1")} name="ownr_addr1">
<Input />
@@ -57,7 +50,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
<Input />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow header={t("owners.forms.contact")}>
<Form.Item
label={t("owners.fields.ownr_ea")}
@@ -71,8 +63,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
>
<FormItemEmail email={getFieldValue("ownr_ea")} />
</Form.Item>
{/* Phone 1 + Type + Opt-out icon */}
<Form.Item label={t("owners.fields.ownr_ph1")} style={{ marginBottom: 0 }}>
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
<Form.Item
@@ -82,11 +72,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
>
<Input style={{ flex: 1, minWidth: "150px" }} />
</Form.Item>
<Form.Item name="ownr_ph1_ty" noStyle>
<Select allowClear placeholder="Type" options={PHONE_TYPE_OPTIONS} style={{ width: 110 }} />
</Form.Item>
{isPhone1OptedOut && (
<Tooltip title={t("consent.text_body")}>
<CloseCircleFilled
@@ -103,8 +88,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
)}
</div>
</Form.Item>
{/* Phone 2 + Type + Opt-out icon */}
<Form.Item label={t("owners.fields.ownr_ph2")} style={{ marginBottom: 0 }}>
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
<Form.Item
@@ -114,11 +97,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
>
<Input style={{ flex: 1, minWidth: "150px" }} />
</Form.Item>
<Form.Item name="ownr_ph2_ty" noStyle>
<Select allowClear placeholder="Type" options={PHONE_TYPE_OPTIONS} style={{ width: 110 }} />
</Form.Item>
{isPhone2OptedOut && (
<Tooltip title={t("consent.text_body")}>
<CloseCircleFilled
@@ -135,7 +113,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
)}
</div>
</Form.Item>
<Form.Item label={t("owners.fields.preferred_contact")} name="preferred_contact">
<Input />
</Form.Item>
@@ -143,7 +120,6 @@ export default function OwnerDetailFormComponent({ form, isPhone1OptedOut, isPho
<Input />
</Form.Item>
</LayoutFormRow>
<Form.Item label={t("owners.fields.note")} name="note">
<Input.TextArea rows={4} />
</Form.Item>

View File

@@ -25,10 +25,8 @@ export default function OwnerDetailUpdateJobsComponent({ owner, selectedJobs, di
ownr_ea: owner["ownr_ea"],
ownr_fn: owner["ownr_fn"],
ownr_ph1: owner["ownr_ph1"],
ownr_ph1_ty: owner["ownr_ph1_ty"],
ownr_ln: owner["ownr_ln"],
ownr_ph2: owner["ownr_ph2"],
ownr_ph2_ty: owner["ownr_ph2_ty"],
ownr_st: owner["ownr_st"],
ownr_title: owner["ownr_title"],
ownr_zip: owner["ownr_zip"]

View File

@@ -47,13 +47,13 @@ export default function OwnerFindModalComponent({
title: t("owners.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
render: (text, record) => <PhoneFormatter type={record.ownr_ph1_ty}>{record.ownr_ph1}</PhoneFormatter>
render: (text, record) => <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>
},
{
title: t("owners.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
render: (text, record) => <PhoneFormatter type={record.ownr_ph2_ty}>{record.ownr_ph2}</PhoneFormatter>
render: (text, record) => <PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>
},
{
title: t("owners.fields.note"),

View File

@@ -15,10 +15,10 @@ export default function OwnerTagPopoverComponent({ job }) {
<OwnerNameDisplay ownerObject={job} />
</Descriptions.Item>
<Descriptions.Item key="2" label={t("jobs.fields.ownr_ph1")}>
<PhoneFormatter type={job.ownr_ph1_ty}>{job.ownr_ph1 || ""}</PhoneFormatter>
<PhoneFormatter>{job.ownr_ph1 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="22" label={t("jobs.fields.ownr_ph2")}>
<PhoneFormatter type={job.ownr_ph2_ty}>{job.ownr_ph2 || ""}</PhoneFormatter>
<PhoneFormatter>{job.ownr_ph2 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="3" label={t("owners.fields.address")}>
{`${job.ownr_addr1 || ""} ${job.ownr_addr2 || ""} ${
@@ -36,10 +36,13 @@ export default function OwnerTagPopoverComponent({ job }) {
<OwnerNameDisplay ownerObject={job.owner} />
</Descriptions.Item>
<Descriptions.Item key="2" label={t("jobs.fields.ownr_ph1")}>
<PhoneFormatter type={job.owner.ownr_ph1_ty}>{job.owner.ownr_ph1 || ""}</PhoneFormatter>
<PhoneFormatter>{job.owner.ownr_ph1 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="22" label={t("jobs.fields.ownr_ph2")}>
<PhoneFormatter>{job.owner.ownr_ph2 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="2" label={t("jobs.fields.ownr_ph2")}>
<PhoneFormatter type={job.owner.ownr_ph2_ty}>{job.owner.ownr_ph2 || ""}</PhoneFormatter>
<PhoneFormatter>{job.owner.ownr_ph2 || ""}</PhoneFormatter>
</Descriptions.Item>
<Descriptions.Item key="3" label={t("owners.fields.address")}>
{`${job.owner.ownr_addr1 || ""} ${job.owner.ownr_addr2 || ""} ${

View File

@@ -39,7 +39,7 @@ export default function OwnersListComponent({ loading, owners, total, refetch })
dataIndex: "ownr_ph1",
key: "ownr_ph1",
render: (text, record) => {
return <PhoneFormatter type={record.ownr_ph1_ty}>{record.ownr_ph1}</PhoneFormatter>;
return <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>;
}
},
{
@@ -47,7 +47,7 @@ export default function OwnersListComponent({ loading, owners, total, refetch })
dataIndex: "ownr_ph2",
key: "ownr_ph2",
render: (text, record) => {
return <PhoneFormatter type={record.ownr_ph2_ty}>{record.ownr_ph2}</PhoneFormatter>;
return <PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>;
}
},
{

View File

@@ -255,14 +255,14 @@ const productionListColumnsData = ({ technician, state, activeStatuses, data, bo
dataIndex: "ownr_ph1",
key: "ownr_ph1",
ellipsis: true,
render: (text, record) => <PhoneFormatter type={record.ownr_ph1_ty}>{record.ownr_ph1}</PhoneFormatter>
render: (text, record) => <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>
},
{
title: i18n.t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
render: (text, record) => <PhoneFormatter type={record.ownr_ph2_ty}>{record.ownr_ph2}</PhoneFormatter>
render: (text, record) => <PhoneFormatter>{record.ownr_ph2}</PhoneFormatter>
},
{
title: i18n.t("jobs.fields.specialcoveragepolicy"),

View File

@@ -154,25 +154,13 @@ export function ProductionListDetail({ bodyshop, jobs, setPrintCenterContext, te
<OwnerNameDisplay ownerObject={theJob} />
{!technician ? (
<>
<StartChatButton
type={data.jobs_by_pk.ownr_ph1_ty}
phone={data.jobs_by_pk.ownr_ph1}
jobid={data.jobs_by_pk.id}
/>
<StartChatButton
type={data.jobs_by_pk.ownr_ph2_ty}
phone={data.jobs_by_pk.ownr_ph2}
jobid={data.jobs_by_pk.id}
/>
<StartChatButton phone={data.jobs_by_pk.ownr_ph1} jobid={data.jobs_by_pk.id} />
<StartChatButton phone={data.jobs_by_pk.ownr_ph2} jobid={data.jobs_by_pk.id} />
</>
) : (
<>
<PhoneNumberFormatter type={data.jobs_by_pk.ownr_ph1_ty}>
{data.jobs_by_pk.ownr_ph1}
</PhoneNumberFormatter>
<PhoneNumberFormatter type={data.jobs_by_pk.ownr_ph2_ty}>
{data.jobs_by_pk.ownr_ph2}
</PhoneNumberFormatter>
<PhoneNumberFormatter>{data.jobs_by_pk.ownr_ph1}</PhoneNumberFormatter>
<PhoneNumberFormatter>{data.jobs_by_pk.ownr_ph2}</PhoneNumberFormatter>
</>
)}
</Space>

View File

@@ -40,8 +40,6 @@ export const QUERY_ALL_ACTIVE_APPOINTMENTS = gql`
ownr_fn
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
ownr_ea
clm_total
id

View File

@@ -19,9 +19,7 @@ export const QUERY_ALL_ACTIVE_JOBS_PAGINATED = gql`
ownr_ln
ownr_co_nm
ownr_ph1
ownr_ph1_ty
ownr_ph2
ownr_ph2_ty
ownr_ea
ownerid
comment
@@ -71,8 +69,6 @@ export const QUERY_ALL_ACTIVE_JOBS = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
ownr_ea
ownerid
comment
@@ -126,8 +122,6 @@ export const QUERY_PARTS_QUEUE = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
ownr_ea
plate_no
plate_st
@@ -185,8 +179,6 @@ export const QUERY_EXACT_JOB_IN_PRODUCTION = gql`
clm_total
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
special_coverage_policy
owner_owing
production_vars
@@ -257,8 +249,6 @@ export const QUERY_EXACT_JOBS_IN_PRODUCTION = gql`
clm_total
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
special_coverage_policy
owner_owing
production_vars
@@ -625,8 +615,6 @@ export const GET_JOB_BY_PK = gql`
ownr_ln
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
ownr_st
ownr_zip
tax_number
@@ -643,8 +631,6 @@ export const GET_JOB_BY_PK = gql`
ownr_ln
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
ownr_st
ownr_zip
parts_tax_rates
@@ -728,7 +714,7 @@ export const GET_JOB_BY_PK = gql`
v_model_yr
v_model_desc
v_vin
notes(where: { pinned: { _eq: true } }, order_by: { updated_at: desc }) {
notes(where:{pinned: {_eq: true}}, order_by: {updated_at: desc}) {
created_at
created_by
critical
@@ -844,8 +830,6 @@ export const QUERY_JOB_CARD_DETAILS = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
comment
ownr_ea
ca_gst_registrant
@@ -1016,6 +1000,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
key
type
}
}
}
`;
@@ -1245,8 +1230,6 @@ export const GET_JOB_INFO_FOR_STRIPE = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
ownr_ea
}
}
@@ -1460,10 +1443,8 @@ export const QUERY_JOB_FOR_DUPE = gql`
ownr_ln
ownr_ph1
ownr_ph1x
ownr_ph1_ty
ownr_ph2
ownr_ph2x
ownr_ph2_ty
ownr_st
ownr_title
ownr_zip
@@ -1709,10 +1690,8 @@ export const QUERY_ALL_JOB_FIELDS = gql`
ownr_ln
ownr_ph1
ownr_ph1x
ownr_ph1_ty
ownr_ph2
ownr_ph2x
ownr_ph2_ty
ownr_st
ownr_title
ownr_zip
@@ -1850,8 +1829,6 @@ export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
plate_no
plate_st
v_vin
@@ -1892,8 +1869,6 @@ export const QUERY_SIMPLIFIED_PARTS_PAGINATED_STATUS_FILTERED = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
plate_no
plate_st
v_vin
@@ -2142,8 +2117,6 @@ export const GET_JOB_FOR_CC_CONTRACT = gql`
ownr_zip
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
}
}
`;
@@ -2442,7 +2415,7 @@ export const QUERY_PARTS_QUEUE_CARD_DETAILS = gql`
start
status
}
notes(where: { pinned: { _eq: true } }, order_by: { updated_at: desc }) {
notes(where:{pinned: {_eq: true}}, order_by: {updated_at: desc}) {
created_at
created_by
critical
@@ -2530,8 +2503,6 @@ export const QUERY_PARTS_QUEUE_CARD_DETAILS = gql`
ownr_ln
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
owner {
id
preferred_contact
@@ -2629,8 +2600,6 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
clm_total
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
special_coverage_policy
owner_owing
production_vars

View File

@@ -8,8 +8,6 @@ export const QUERY_SEARCH_OWNER_BY_IDX = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
ownr_addr1
ownr_addr2
ownr_city
@@ -59,10 +57,8 @@ export const QUERY_OWNER_BY_ID = gql`
ownr_ea
ownr_fn
ownr_ph1
ownr_ph1_ty
ownr_ln
ownr_ph2
ownr_ph2_ty
ownr_st
ownr_title
ownr_zip
@@ -116,10 +112,8 @@ export const QUERY_ALL_OWNERS = gql`
ownr_ea
ownr_fn
ownr_ph1
ownr_ph1_ty
ownr_ln
ownr_ph2
ownr_ph2_ty
ownr_st
ownr_title
ownr_zip
@@ -142,10 +136,8 @@ export const QUERY_ALL_OWNERS_PAGINATED = gql`
ownr_ea
ownr_fn
ownr_ph1
ownr_ph1_ty
ownr_ln
ownr_ph2
ownr_ph2_ty
ownr_st
ownr_title
ownr_zip
@@ -172,10 +164,8 @@ export const QUERY_OWNER_FOR_JOB_CREATION = gql`
ownr_ea
ownr_fn
ownr_ph1
ownr_ph1_ty
ownr_ln
ownr_ph2
ownr_ph2_ty
ownr_st
ownr_title
ownr_zip

View File

@@ -177,12 +177,10 @@ export const QUERY_PARTS_ORDER_OEC = gql`
ownr_fax
ownr_faxx
ownr_ph1
ownr_ph1_ty
ownr_fn
ownr_ln
ownr_ph1x
ownr_ph2
ownr_ph2_ty
ownr_ph2x
ownr_st
ownr_title

View File

@@ -22,8 +22,6 @@ export const GLOBAL_SEARCH_QUERY = gql`
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_ph1_ty
ownr_ph2_ty
}
search_vehicles(args: { search: $search }, limit: 25) {
id

View File

@@ -2590,10 +2590,7 @@
"fromclaim": "Current Claim",
"fromowner": "Historical Owner Record",
"relatedjobs": "Related Jobs",
"updateowner": "Update Owner",
"work": "Work",
"home": "Home",
"cell": "Cell"
"updateowner": "Update Owner"
},
"successes": {
"delete": "Owner deleted successfully.",

View File

@@ -2590,10 +2590,7 @@
"fromclaim": "",
"fromowner": "",
"relatedjobs": "",
"updateowner": "",
"work": "",
"home": "",
"cell": ""
"updateowner": ""
},
"successes": {
"delete": "",

View File

@@ -2590,10 +2590,7 @@
"fromclaim": "",
"fromowner": "",
"relatedjobs": "",
"updateowner": "",
"work": "",
"home": "",
"cell": ""
"updateowner": ""
},
"successes": {
"delete": "",

View File

@@ -1,23 +1,7 @@
import { Typography } from "antd";
//import NumberFormat from "react-number-format";
import parsePhoneNumber from "libphonenumber-js";
const { Text } = Typography;
export default function PhoneNumberFormatter({ children, type }) {
const p = parsePhoneNumber(children || "", "CA");
if (!p) return null;
const phone = p.formatNational();
return (
<span>
<Text>{phone}</Text>
{type ? (
<>
{" "}
<Text type="secondary">({type})</Text>
</>
) : null}
</span>
);
export default function PhoneNumberFormatter(props) {
const p = parsePhoneNumber(props.children || "", "CA");
return p ? <span>{p.formatNational()}</span> : null;
}

View File

@@ -3684,7 +3684,6 @@
- completed_tasks
- converted
- created_at
- created_user_email
- cust_pr
- date_estimated
- date_exported
@@ -3799,10 +3798,8 @@
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1_ty
- ownr_ph1x
- ownr_ph2
- ownr_ph2_ty
- ownr_ph2x
- ownr_st
- ownr_title
@@ -3964,7 +3961,6 @@
- completed_tasks
- converted
- created_at
- created_user_email
- cust_pr
- date_estimated
- date_exported
@@ -4081,10 +4077,8 @@
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1_ty
- ownr_ph1x
- ownr_ph2
- ownr_ph2_ty
- ownr_ph2x
- ownr_st
- ownr_title
@@ -4257,7 +4251,6 @@
- completed_tasks
- converted
- created_at
- created_user_email
- cust_pr
- date_estimated
- date_exported
@@ -4374,10 +4367,8 @@
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1_ty
- ownr_ph1x
- ownr_ph2
- ownr_ph2_ty
- ownr_ph2x
- ownr_st
- ownr_title
@@ -4650,7 +4641,7 @@
request_transform:
body:
action: transform
template: "{\r\n \"event\": {\r\n \"session_variables\": {\r\n \"x-hasura-user-id\": {{$body?.event?.session_variables?.x-hasura-user-id ?? \"Internal\"}},\r\n \"x-hasura-role\": {{$body?.event?.session_variables?.x-hasura-role ?? \"Internal\"}}\r\n }, \r\n \"op\": {{$body.event.op}},\r\n \"data\": {\r\n \"new\": {\r\n \"id\": {{$body.event.data.new.id}},\r\n \"shopid\": {{$body.event.data.new?.shopid}},\r\n \"ro_number\": {{$body.event.data.new?.ro_number}},\r\n \"created_user_email\": {{$body.event.data.new?.created_user_email}}\r\n }\r\n }\r\n },\r\n \"trigger\": {\r\n \"name\": \"notifications_jobs_autoadd\"\r\n },\r\n \"table\": {\r\n \"schema\": \"public\",\r\n \"name\": \"jobs\"\r\n }\r\n}\r\n"
template: "{\r\n \"event\": {\r\n \"session_variables\": {\r\n \"x-hasura-user-id\": {{$body?.event?.session_variables?.x-hasura-user-id ?? \"Internal\"}},\r\n \"x-hasura-role\": {{$body?.event?.session_variables?.x-hasura-role ?? \"Internal\"}}\r\n }, \r\n \"op\": {{$body.event.op}},\r\n \"data\": {\r\n \"new\": {\r\n \"id\": {{$body.event.data.new.id}},\r\n \"shopid\": {{$body.event.data.new?.shopid}},\r\n \"ro_number\": {{$body.event.data.new?.ro_number}}\r\n }\r\n }\r\n },\r\n \"trigger\": {\r\n \"name\": \"notifications_jobs_autoadd\"\r\n },\r\n \"table\": {\r\n \"schema\": \"public\",\r\n \"name\": \"jobs\"\r\n }\r\n}\r\n"
method: POST
query_params: {}
template_engine: Kriti
@@ -5177,9 +5168,7 @@
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1_ty
- ownr_ph2
- ownr_ph2_ty
- ownr_st
- ownr_title
- ownr_zip
@@ -5204,9 +5193,7 @@
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1_ty
- ownr_ph2
- ownr_ph2_ty
- ownr_st
- ownr_title
- ownr_zip
@@ -5242,9 +5229,7 @@
- ownr_fn
- ownr_ln
- ownr_ph1
- ownr_ph1_ty
- ownr_ph2
- ownr_ph2_ty
- ownr_st
- ownr_title
- ownr_zip

View File

@@ -1,4 +0,0 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."owners" add column "ownr_ph1_ty" text
-- null;

View File

@@ -1,2 +0,0 @@
alter table "public"."owners" add column "ownr_ph1_ty" text
null;

View File

@@ -1,4 +0,0 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."owners" add column "ownr_ph2_ty" text
-- null;

View File

@@ -1,2 +0,0 @@
alter table "public"."owners" add column "ownr_ph2_ty" text
null;

View File

@@ -1,4 +0,0 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "ownr_ph1_ty" text
-- null;

View File

@@ -1,2 +0,0 @@
alter table "public"."jobs" add column "ownr_ph1_ty" text
null;

View File

@@ -1,4 +0,0 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "ownr_ph2_ty" text
-- null;

View File

@@ -1,2 +0,0 @@
alter table "public"."jobs" add column "ownr_ph2_ty" text
null;

View File

@@ -283,6 +283,11 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
VendorRef: {
value: vendor.Id
},
...(vendor.TermRef && {
SalesTermRef: {
value: vendor.TermRef.value
}
}),
TxnDate: moment(bill.date)
//.tz(bill.job.bodyshop.timezone)
.format("YYYY-MM-DD"),