import { useMutation, useQuery } from "@apollo/client"; import { Button, Card, Col, Form, InputNumber, Popover, Row, Select } from "antd"; import axios from "axios"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { GET_LINE_TICKET_BY_PK } from "../../graphql/jobs-lines.queries"; import { UPDATE_JOB_STATUS } from "../../graphql/jobs.queries"; import { UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries"; import { selectTechnician } from "../../redux/tech/tech.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { CalculateAllocationsTotals } from "../labor-allocations-table/labor-allocations-table.utility"; import TechJobClockoutDelete from "../tech-job-clock-out-delete/tech-job-clock-out-delete.component"; import { LaborAllocationContainer } from "../time-ticket-modal/time-ticket-modal.component"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, technician: selectTechnician }); export function TechClockOffButton({ bodyshop, technician, jobId, timeTicketId, completedCallback, isShiftTicket, otherBtnProps }) { const [loading, setLoading] = useState(false); const [updateTimeticket] = useMutation(UPDATE_TIME_TICKET); const [updateJobStatus] = useMutation(UPDATE_JOB_STATUS); const notification = useNotification(); const [form] = Form.useForm(); const { treatments: { Enhanced_Payroll } } = useSplitTreatments({ attributes: {}, names: ["Enhanced_Payroll"], splitKey: bodyshop.imexshopid }); const { queryLoading, data: lineTicketData } = useQuery(GET_LINE_TICKET_BY_PK, { variables: { id: jobId }, skip: !jobId, fetchPolicy: "network-only", nextFetchPolicy: "network-only" }); const { t } = useTranslation(); const emps = bodyshop.employees.filter((e) => e.id === (technician && technician.id))[0]; const handleFinish = async (values) => { logImEXEvent("tech_clock_out_job"); const status = values.status; delete values.status; setLoading(true); const result = await updateTimeticket({ variables: { timeticketId: timeTicketId, timeticket: { clockoff: (await axios.post("/utils/time")).data, ...values, rate: emps && emps.rates.filter((r) => r.cost_center === values.cost_center)[0]?.rate, flat_rate: emps && emps.flat_rate, ciecacode: bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatment === "on" ? values.cost_center : Object.keys(bodyshop.md_responsibility_centers.defaults.costs).find((key) => { return bodyshop.md_responsibility_centers.defaults.costs[key] === values.cost_center; }) } } }); if (result.errors) { notification["error"]({ message: t("timetickets.errors.clockingout", { message: JSON.stringify(result.errors) }) }); } else { notification["success"]({ message: t("timetickets.successes.clockedout") }); } if (!isShiftTicket) { const job_update_result = await updateJobStatus({ variables: { jobId: jobId, status: status } }); if (job_update_result.errors) { notification["error"]({ message: t("jobs.errors.updating", { message: JSON.stringify(result.errors) }) }); } else { notification["success"]({ message: t("jobs.successes.updated") }); } } setLoading(false); if (completedCallback) completedCallback(); }; const overlay = (
{!isShiftTicket ? (
({ validator(rule, value) { if (!bodyshop.tt_enforce_hours_for_tech_console) { return Promise.resolve(); } if (!value || getFieldValue("cost_center") === null || !lineTicketData) return Promise.resolve(); //Check the cost center, const totals = CalculateAllocationsTotals( bodyshop, lineTicketData.joblines, lineTicketData.timetickets, lineTicketData.jobs_by_pk.lbr_adjustments ); const fieldTypeToCheck = bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? "mod_lbr_ty" : "cost_center"; const costCenterDiff = Math.round( totals.find((total) => total[fieldTypeToCheck] === getFieldValue("cost_center")) ?.difference * 10 ) / 10; if (value > costCenterDiff) return Promise.reject(t("timetickets.validation.hoursenteredmorethanavailable")); else { return Promise.resolve(); } } }) ]} >
) : null} {isShiftTicket ? (
) : ( )} {!isShiftTicket && ( )}
); return ( ); } export default connect(mapStateToProps, null)(TechClockOffButton);