import { BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined, WarningFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; import { Card, Checkbox, Col, Divider, Row, Space, Tag, Tooltip } from "antd"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Link } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions.js"; import { selectIsPartsEntry, selectJobReadOnly } from "../../redux/application/application.selectors"; import { setModalContext } from "../../redux/modals/modals.actions"; import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings.js"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateTimeFormatter, DateTimeFormatterFunction } from "../../utils/DateFormatter"; import dayjs from "../../utils/day"; import PhoneNumberFormatter from "../../utils/PhoneFormatter"; import ChatOpenButton from "../chat-open-button/chat-open-button.component"; import DataLabel from "../data-label/data-label.component"; import JobAltTransportChange from "../job-at-change/job-at-change.component"; import JobEmployeeAssignments from "../job-employee-assignments/job-employee-assignments.container"; import JobsRelatedRos from "../jobs-related-ros/jobs-related-ros.component"; import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component"; import PinnedJobNotes from "../pinned-job-notes/pinned-job-notes.component.jsx"; import ProductionListColumnComment from "../production-list-columns/production-list-columns.comment.component"; import ProductionListColumnProductionNote from "../production-list-columns/production-list-columns.productionnote.component"; import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component"; import "./jobs-detail-header.styles.scss"; import getPartsBasePath from "../../utils/getPartsBasePath.js"; const mapStateToProps = createStructuredSelector({ jobRO: selectJobReadOnly, bodyshop: selectBodyshop, isPartsEntry: selectIsPartsEntry }); const mapDispatchToProps = (dispatch) => ({ setPrintCenterContext: (context) => dispatch( setModalContext({ context: context, modal: "printCenter" }) ), insertAuditTrail: ({ jobid, operation, type }) => dispatch( insertAuditTrail({ jobid, operation, type }) ) }); export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, isPartsEntry }) { const { t } = useTranslation(); const { notification } = useNotification(); const [notesClamped, setNotesClamped] = useState(true); const [updateJob] = useMutation(UPDATE_JOB); const basePath = getPartsBasePath(isPartsEntry); const colSpan = { xs: { span: 24 }, sm: { span: 24 }, md: { span: isPartsEntry ? 8 : 12 }, lg: { span: isPartsEntry ? 8 : 6 }, xl: { span: isPartsEntry ? 8 : 6 } }; const vehicleTitle = `${job.v_model_yr || ""} ${job.v_color || ""} ${job.v_make_desc || ""} ${job.v_model_desc || ""}`.trim(); const bodyHrs = job.joblines.filter((j) => j.mod_lbr_ty !== "LAR").reduce((acc, val) => acc + val.mod_lb_hrs, 0); const refinishHrs = job.joblines .filter((line) => line.mod_lbr_ty === "LAR") .reduce((acc, val) => acc + val.mod_lb_hrs, 0); const ownerTitle = OwnerNameDisplayFunction(job).trim(); // Handle checkbox changes const handleCheckboxChange = async (field, checked) => { const value = checked ? dayjs().toISOString() : null; try { const ret = await updateJob({ variables: { jobId: job.id, job: { [field]: value } }, refetchQueries: ["GET_JOB_BY_PK"], awaitRefetchQueries: true }); insertAuditTrail({ jobid: job.id, operation: AuditTrailMapping.jobfieldchange( field, ret.data.update_jobs.returning[0][field] ? DateTimeFormatterFunction(ret.data.update_jobs.returning[0][field]) : checked ), type: "jobfieldchange" }); } catch (error) { notification.error({ message: t("jobs.errors.saving", { error: error.message }) }); } }; return ( <>
{job.status} {job.inproduction && {t("jobs.labels.inproduction")}} {job.suspended && } {job.iouparent && ( )} {job.production_vars && job.production_vars.alert ? ( ) : null} {job.status === bodyshop.md_ro_statuses.default_scheduled && job.scheduled_in ? ( {job.scheduled_in} ) : null} {!isPartsEntry && {job.ins_co_nm}} {job.clm_no} {job.po_number} {!isPartsEntry && ( {job.clm_total} / {job.owner_owing} )} {!isPartsEntry && ( <> {job.alt_transport} {job?.cccontracts?.length > 0 && ( {job.cccontracts.map((c, index) => ( {`${c.agreementnumber} - ${c.courtesycar.fleetnumber} ${c.courtesycar.year} ${c.courtesycar.make} ${c.courtesycar.model}`} {index !== job.cccontracts.length - 1 ? "," : null} ))} )} handleCheckboxChange("estimate_sent_approval", e.target.checked)} disabled={disabled || isPartsEntry} > {job.estimate_sent_approval && ( {job.estimate_sent_approval} )} handleCheckboxChange("estimate_approved", e.target.checked)} disabled={disabled || isPartsEntry} > {job.estimate_approved && ( {job.estimate_approved} )} {job.special_coverage_policy && ( {t("jobs.labels.specialcoveragepolicy")} )} {job.ca_gst_registrant && ( {t("jobs.fields.ca_gst_registrant")} )} {job.hit_and_run && ( {t("jobs.fields.hit_and_run")} )} )}
{ownerTitle.length > 0 ? ownerTitle : t("owner.labels.noownerinfo")} ) : ( {ownerTitle.length > 0 ? ownerTitle : t("owner.labels.noownerinfo")} ) } >
{disabled || isPartsEntry ? ( {job.ownr_ph1} ) : ( )} {disabled || isPartsEntry ? ( {job.ownr_ph2} ) : ( )} {`${job.ownr_addr1 || ""} ${job.ownr_addr2 || ""} ${ job.ownr_city || "" } ${job.ownr_st || ""} ${job.ownr_zip || ""}`} {disabled || isPartsEntry ? ( <>{job.ownr_ea || ""} ) : job.ownr_ea ? ( {job.ownr_ea} ) : null} {job.owner?.tax_number && ( {job.owner?.tax_number || ""} )} {job.owner?.note || ""}
{vehicleTitle.length > 0 ? vehicleTitle : t("vehicles.labels.novehinfo")} ) : ( {vehicleTitle.length > 0 ? vehicleTitle : t("vehicles.labels.novehinfo")} ) ) : ( ) } >
{`${job.plate_no || t("general.labels.na")} (${`${job.plate_st || t("general.labels.na")}`})`} {`${job.v_vin || t("general.labels.na")}`} {bodyshop.pbs_serialnumber || bodyshop.cdk_dealerid ? ( job.v_vin?.length !== 17 ? ( ) : null ) : null} {job.regie_number || t("general.labels.na")} {job.vehicle?.notes && ( setNotesClamped(!notesClamped)} > {job.vehicle.notes} )} {job.vehicle?.v_paint_codes && ( {Object.keys(job.vehicle.v_paint_codes) .filter( (key) => job.vehicle.v_paint_codes[key] !== "" && job.vehicle.v_paint_codes[key] !== null && job.vehicle.v_paint_codes[key] !== undefined ) .map((key, idx) => ( {job.vehicle.v_paint_codes[key]} ))} )}
{!isPartsEntry && ( {t("jobs.labels.employeeassignments")}} id={"job-employee-assignments"} >
{bodyHrs.toFixed(1)} / {refinishHrs.toFixed(1)} / {(bodyHrs + refinishHrs).toFixed(1)}
)}
); } export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailHeader);