import { EditFilled } from "@ant-design/icons"; import { Card, Col, Row, Space, Table, Typography } from "antd"; import _ from "lodash"; import React, { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectTechnician } from "../../redux/tech/tech.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { alphaSort } from "../../utils/sorters"; import LaborAllocationsAdjustmentEdit from "../labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component"; import "./labor-allocations-table.styles.scss"; import { CalculateAllocationsTotals } from "./labor-allocations-table.utility"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, technician: selectTechnician, }); export function LaborAllocationsTable({ jobId, joblines, timetickets, bodyshop, adjustments, technician, }) { const { t } = useTranslation(); const [totals, setTotals] = useState([]); const [state, setState] = useState({ sortedInfo: { columnKey: "cost_center", field: "cost_center", order: "ascend", }, filteredInfo: {}, }); useEffect(() => { if (!!joblines && !!timetickets && !!bodyshop); setTotals( CalculateAllocationsTotals(bodyshop, joblines, timetickets, adjustments) ); if (!jobId) setTotals([]); }, [joblines, timetickets, bodyshop, adjustments, jobId]); const convertedLines = useMemo( () => joblines && joblines.filter((j) => j.convertedtolbr), [joblines] ); const columns = [ { title: t("timetickets.fields.cost_center"), dataIndex: "cost_center", key: "cost_center", defaultSortOrder: "cost_center", sorter: (a, b) => alphaSort(a.cost_center, b.cost_center), sortOrder: state.sortedInfo.columnKey === "cost_center" && state.sortedInfo.order, render: (text, record) => `${record.cost_center} (${record.mod_lbr_ty})`, }, { title: t("jobs.labels.hrs_total"), dataIndex: "total", key: "total", sorter: (a, b) => a.total - b.total, sortOrder: state.sortedInfo.columnKey === "total" && state.sortedInfo.order, render: (text, record) => record.total.toFixed(1), }, { title: t("jobs.labels.hrs_claimed"), dataIndex: "hrs_claimed", key: "hrs_claimed", sorter: (a, b) => a.claimed - b.claimed, sortOrder: state.sortedInfo.columnKey === "claimed" && state.sortedInfo.order, render: (text, record) => record.claimed && record.claimed.toFixed(1), }, { title: t("jobs.labels.adjustments"), dataIndex: "adjustments", key: "adjustments", sorter: (a, b) => a.adjustments - b.adjustments, sortOrder: state.sortedInfo.columnKey === "adjustments" && state.sortedInfo.order, render: (text, record) => ( {record.adjustments.toFixed(1)} {!technician && ( )} ), }, { title: t("jobs.labels.difference"), dataIndex: "difference", key: "difference", sorter: (a, b) => a.difference - b.difference, sortOrder: state.sortedInfo.columnKey === "difference" && state.sortedInfo.order, render: (text, record) => ( = 0 ? "green" : "red", }} > {_.round(record.difference, 1)} ), }, ]; const convertedTableCols = [ { title: t("joblines.fields.line_desc"), dataIndex: "line_desc", key: "line_desc", ellipsis: true, }, { title: t("joblines.fields.op_code_desc"), dataIndex: "op_code_desc", key: "op_code_desc", ellipsis: true, render: (text, record) => `${record.op_code_desc || ""}${ record.alt_partm ? ` ${record.alt_partm}` : "" }`, }, { title: t("joblines.fields.act_price"), dataIndex: "act_price", key: "act_price", ellipsis: true, render: (text, record) => ( <> {record.db_ref === "900510" || record.db_ref === "900511" ? record.prt_dsmk_m : record.act_price} {record.prt_dsmk_p && record.prt_dsmk_p !== 0 ? ( {`(${record.prt_dsmk_p}%)`} ) : ( <> )} ), }, { title: t("joblines.fields.part_qty"), dataIndex: "part_qty", key: "part_qty", }, { title: t("joblines.fields.mod_lbr_ty"), dataIndex: "conv_mod_lbr_ty", key: "conv_mod_lbr_ty", render: (text, record) => record.convertedtolbr_data && record.convertedtolbr_data.mod_lbr_ty, }, { title: t("joblines.fields.mod_lb_hrs"), dataIndex: "conv_mod_lb_hrs", key: "conv_mod_lb_hrs", render: (text, record) => record.convertedtolbr_data && record.convertedtolbr_data.mod_lb_hrs && record.convertedtolbr_data.mod_lb_hrs.toFixed(1), }, ]; const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); }; const summary = totals && totals.reduce( (acc, val) => { acc.hrs_total += val.total; acc.hrs_claimed += val.claimed; acc.adjustments += val.adjustments; acc.difference += val.difference; return acc; }, { hrs_total: 0, hrs_claimed: 0, adjustments: 0, difference: 0 } ); return ( `${record.cost_center} ${record.mod_lbr_ty}`} pagination={false} onChange={handleTableChange} dataSource={totals} scroll={{ x: true, }} summary={() => ( {t("general.labels.totals")} {summary.hrs_total.toFixed(1)} {summary.hrs_claimed.toFixed(1)} {summary.adjustments.toFixed(1)} = 0 ? "green" : "red", }} > {summary.difference.toFixed(1)} )} /> {convertedLines && convertedLines.length > 0 && (
)} ); } export default connect(mapStateToProps, null)(LaborAllocationsTable);