Compare commits

..

2 Commits

Author SHA1 Message Date
Allan Carr
cca23a5b11 IO-3509 Correction for date_estimate to handle tz correctly
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2026-01-23 23:07:11 -08:00
Allan Carr
2acddcb9ac IO-3509 Duplicate Job Open Estimate Date
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2026-01-23 22:51:53 -08:00
8 changed files with 61 additions and 66 deletions

View File

@@ -50,7 +50,8 @@ export function JobCreateIOU({ bodyshop, currentUser, job, selectedJobLines, tec
config: {
status: bodyshop.md_ro_statuses.default_open,
bodyshopid: bodyshop.id,
useremail: currentUser.email
useremail: currentUser.email,
timezone: bodyshop.timezone
},
currentUser
});

View File

@@ -264,7 +264,7 @@ export function JobsDetailHeaderActions({
DuplicateJob({
apolloClient: client,
jobId: job.id,
config: { defaultOpenStatus: bodyshop.md_ro_statuses.default_imported },
config: { defaultOpenStatus: bodyshop.md_ro_statuses.default_imported, timezone: bodyshop.timezone },
completionCallback: (newJobId) => {
history(`/manage/jobs/${newJobId}`);
notification.success({
@@ -279,7 +279,7 @@ export function JobsDetailHeaderActions({
DuplicateJob({
apolloClient: client,
jobId: job.id,
config: { defaultOpenStatus: bodyshop.md_ro_statuses.default_imported },
config: { defaultOpenStatus: bodyshop.md_ro_statuses.default_imported, timezone: bodyshop.timezone },
completionCallback: (newJobId) => {
history(`/manage/jobs/${newJobId}`);
notification.success({

View File

@@ -15,7 +15,7 @@ export default async function DuplicateJob({
}) {
logImEXEvent("job_duplicate");
const { defaultOpenStatus } = config;
const { defaultOpenStatus, timezone } = config;
//get a list of all fields on the job
const res = await apolloClient.query({
query: QUERY_JOB_FOR_DUPE,
@@ -31,9 +31,12 @@ export default async function DuplicateJob({
delete existingJob.updatedat;
delete existingJob.cieca_stl;
delete existingJob.cieca_ttl;
!keepJobLines && delete existingJob.clm_total;
const newJob = {
...existingJob,
date_estimated: dayjs().tz(timezone, false).format("YYYY-MM-DD"),
date_open: dayjs(),
status: defaultOpenStatus
};
@@ -70,7 +73,7 @@ export default async function DuplicateJob({
export async function CreateIouForJob({ apolloClient, jobId, config, jobLinesToKeep, currentUser }) {
logImEXEvent("job_create_iou");
const { status } = config;
const { status, timezone } = config;
//get a list of all fields on the job
const res = await apolloClient.query({
query: QUERY_JOB_FOR_DUPE,
@@ -88,10 +91,10 @@ export async function CreateIouForJob({ apolloClient, jobId, config, jobLinesToK
const newJob = {
...existingJob,
converted: true,
status: status,
iouparent: jobId,
date_estimated: dayjs().tz(timezone, false).format("YYYY-MM-DD"),
date_open: dayjs(),
audit_trails: {
data: [

View File

@@ -9,7 +9,6 @@ import { TemplateList } from "../../utils/TemplateConstants";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { HistoryOutlined, MailOutlined, PrinterOutlined, UnorderedListOutlined } from "@ant-design/icons";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
const mapStateToProps = createStructuredSelector({
printCenterModal: selectPrintCenter,
@@ -30,29 +29,27 @@ export function PrintCenterJobsPartsComponent({ printCenterModal, bodyshop, tech
names: ["Enhanced_Payroll"],
splitKey: bodyshop.imexshopid
});
const hasDMSKey = bodyshopHasDmsKey(bodyshop);
const Templates = !hasDMSKey
? Object.keys(tempList)
.map((key) => tempList[key])
.filter(
(temp) =>
(!temp.regions ||
const Templates =
bodyshop.cdk_dealerid === null && bodyshop.pbs_serialnumber === null
? Object.keys(tempList)
.map((key) => tempList[key])
.filter(
(temp) =>
(!temp.regions ||
temp.regions?.[bodyshop.region_config] ||
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)) &&
(!temp.dms || temp.dms === false)
)
: Object.keys(tempList)
.map((key) => tempList[key])
.filter(
(temp) =>
!temp.regions ||
temp.regions?.[bodyshop.region_config] ||
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)) &&
(!temp.dms || temp.dms === false)
)
.filter((temp) => !technician || temp.group !== "financial")
: Object.keys(tempList)
.map((key) => tempList[key])
.filter(
(temp) =>
!temp.regions ||
temp.regions?.[bodyshop.region_config] ||
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)
)
.filter((temp) => !technician || temp.group !== "financial");
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)
);
const JobsReportsList =
Enhanced_Payroll.treatment === "on"
? Object.keys(Templates)

View File

@@ -12,18 +12,15 @@ import Jobd3RdPartyModal from "../job-3rd-party-modal/job-3rd-party-modal.compon
import PrintCenterItem from "../print-center-item/print-center-item.component";
import PrintCenterJobsLabels from "../print-center-jobs-labels/print-center-jobs-labels.component";
import PrintCenterSpeedPrint from "../print-center-speed-print/print-center-speed-print.component";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils";
import { selectTechnician } from "../../redux/tech/tech.selectors";
const mapStateToProps = createStructuredSelector({
printCenterModal: selectPrintCenter,
bodyshop: selectBodyshop,
technician: selectTechnician
bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({});
export function PrintCenterJobsComponent({ printCenterModal, bodyshop, technician }) {
export function PrintCenterJobsComponent({ printCenterModal, bodyshop }) {
const [search, setSearch] = useState("");
const { id: jobId, job } = printCenterModal.context;
const tempList = TemplateList("job", {});
@@ -35,33 +32,30 @@ export function PrintCenterJobsComponent({ printCenterModal, bodyshop, technicia
names: ["Enhanced_Payroll"],
splitKey: bodyshop.imexshopid
});
const hasDMSKey = bodyshopHasDmsKey(bodyshop);
const Templates = !hasDMSKey
? Object.keys(tempList)
.map((key) => {
return tempList[key];
})
.filter(
(temp) =>
(!temp.regions ||
const Templates =
bodyshop.cdk_dealerid === null && bodyshop.pbs_serialnumber === null
? Object.keys(tempList)
.map((key) => {
return tempList[key];
})
.filter(
(temp) =>
(!temp.regions ||
(temp.regions && temp.regions[bodyshop.region_config]) ||
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)) &&
(!temp.dms || temp.dms === false)
)
: Object.keys(tempList)
.map((key) => {
return tempList[key];
})
.filter(
(temp) =>
!temp.regions ||
(temp.regions && temp.regions[bodyshop.region_config]) ||
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)) &&
(!temp.dms || temp.dms === false)
)
.filter((temp) => !technician || temp.group !== "financial")
: Object.keys(tempList)
.map((key) => {
return tempList[key];
})
.filter(
(temp) =>
!temp.regions ||
(temp.regions && temp.regions[bodyshop.region_config]) ||
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)
)
.filter((temp) => !technician || temp.group !== "financial");
(temp.regions && bodyshop.region_config.includes(Object.keys(temp.regions)) === true)
);
const JobsReportsList =
Enhanced_Payroll.treatment === "on"
? Object.keys(Templates)
@@ -95,7 +89,7 @@ export function PrintCenterJobsComponent({ printCenterModal, bodyshop, technicia
<Space wrap>
<PrintCenterJobsLabels jobId={jobId} />
<Jobd3RdPartyModal jobId={jobId} job={job} />
<Input.Search onChange={(e) => setSearch(e.target.value)} value={search} enterButton />
<Input.Search onChange={(e) => setSearch(e.target.value)} value={search} />
</Space>
}
>

View File

@@ -59,8 +59,7 @@ export function TechLookupJobsDrawer({ bodyshop, setPrintCenterContext }) {
const handleDrawerClose = () => {
// Immutable omit (no delete/mutation)
const { selected, ...rest } = searchParams || {};
void selected;
const { ...rest } = searchParams || {};
history({
search: queryString.stringify(rest)
});
@@ -73,6 +72,7 @@ export function TechLookupJobsDrawer({ bodyshop, setPrintCenterContext }) {
{data ? (
<PageHeader
onBack={() => window.history.back()}
title={data.jobs_by_pk.ro_number || t("general.labels.na")}
extra={
<Button

View File

@@ -47,14 +47,14 @@ exports.totalsSsu = async function (req, res) {
throw new Error("Failed to update job totals");
}
res.status(200).send();
res.status(200).json({ success: true });
} catch (error) {
logger.log("job-totals-ssu-USA-error", "error", req?.user?.email, id, {
jobid: id,
error: error.message,
stack: error.stack
});
res.status(503).send();
res.status(503).json({ error: "Failed to calculate totals" });
}
};

View File

@@ -47,14 +47,14 @@ exports.totalsSsu = async function (req, res) {
throw new Error("Failed to update job totals");
}
res.status(200).send();
res.status(200).json({ success: true });
} catch (error) {
logger.log("job-totals-ssu-error", "error", req.user.email, id, {
jobid: id,
error: error.message,
stack: error.stack
});
res.status(503).send();
res.status(503).json({ error: "Failed to calculate totals" });
}
};