import { Card, Col, Row, Table } from "antd"; import _ from "lodash"; import moment from "moment"; import React, { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { onlyUnique } from "../../utils/arrayHelper"; import { alphaSort } from "../../utils/sorters"; import { TemplateList } from "../../utils/TemplateConstants"; import PrintWrapperComponent from "../print-wrapper/print-wrapper.component"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, }); const mapDispatchToProps = (dispatch) => ({ //setUserLanguage: language => dispatch(setUserLanguage(language)) }); export function TimeTicketsSummaryEmployees({ bodyshop, loading, timetickets, startDate, endDate, }) { //Group everything by employee //Then sum the individual time TimeTicketsSummary. //Calculate job based tickets. const jobTicketsByEmployee = {}; timetickets .filter((i) => i.cost_center !== "timetickets.labels.shift") .map((tt) => { if (!!!jobTicketsByEmployee[tt.employeeid]) { jobTicketsByEmployee[tt.employeeid] = []; } jobTicketsByEmployee[tt.employeeid].push(tt); return null; }); const jobTickets = Object.keys(jobTicketsByEmployee).map(function (key) { return { jobKey: key, employee: jobTicketsByEmployee[key][0].employee, tickets: jobTicketsByEmployee[key], }; }); //Calculate shift based tickets. const shiftTicketsByEmployee = {}; timetickets .filter((i) => i.cost_center === "timetickets.labels.shift") .map((tt) => { if (!!!shiftTicketsByEmployee[tt.employeeid]) { shiftTicketsByEmployee[tt.employeeid] = []; } shiftTicketsByEmployee[tt.employeeid].push(tt); return null; }); const shiftTickets = Object.keys(shiftTicketsByEmployee).map(function (key) { return { employee: shiftTicketsByEmployee[key][0].employee, tickets: shiftTicketsByEmployee[key], }; }); return ( ); } export default connect( mapStateToProps, mapDispatchToProps )(TimeTicketsSummaryEmployees); const JobRelatedTicketsTable = ({ loading, jobTickets, startDate, endDate, }) => { const Templates = TemplateList(); const { t } = useTranslation(); const [state, setState] = useState({ sortedInfo: {}, }); const data = useMemo(() => { return _.flatten( jobTickets.map((item, idx) => { const employeeCostCenters = item.tickets .map((i) => i.cost_center) .filter(onlyUnique); return employeeCostCenters.map((costCenter) => { const actHrs = item.tickets .filter((ticket) => ticket.cost_center === costCenter) .reduce((acc, val) => acc + val.actualhrs, 0); const prodHrs = item.tickets .filter((ticket) => ticket.cost_center === costCenter) .reduce((acc, val) => acc + val.productivehrs, 0); const clockHrs = item.tickets .filter((ticket) => ticket.cost_center === costCenter) .reduce((acc, val) => { if (!!val.clockoff && !!val.clockon) return ( acc + moment(val.clockoff).diff(moment(val.clockon), "hours", true) ); return acc; }, 0); return { id: `${item.jobKey}${costCenter}`, item, actHrs, prodHrs, clockHrs, }; }); }) ); }, [jobTickets]); const columns = [ { title: t("employees.labels.name"), dataIndex: "empname", key: "empname", sorter: (a, b) => alphaSort(a.empname, b.empname), sortOrder: state.sortedInfo.columnKey === "empname" && state.sortedInfo.order, render: (text, record) => `${record.item.employee.first_name} ${record.item.employee.last_name}`, }, { title: t("timetickets.fields.actualhrs"), dataIndex: "actHrs", key: "actHrs", sorter: (a, b) => a.actHrs - b.actHrs, sortOrder: state.sortedInfo.columnKey === "actHrs" && state.sortedInfo.order, }, { title: t("timetickets.fields.productivehrs"), dataIndex: "prodHrs", key: "prodHrs", sorter: (a, b) => a.prodHrs - b.prodHrs, sortOrder: state.sortedInfo.columnKey === "prodHrs" && state.sortedInfo.order, }, { title: t("timetickets.fields.efficiency"), dataIndex: "total", key: "total", sorter: (a, b) => a.total - b.total, sortOrder: state.sortedInfo.columnKey === "total" && state.sortedInfo.order, render: (text, record) => record.actHrs === 0 || !record.actHrs ? "∞" : ((record.prodHrs / record.actHrs) * 100).toFixed(2), }, { title: t("timetickets.fields.clockhours"), dataIndex: "clockHrs", key: "clockHrs", sorter: (a, b) => a.clockHrs - b.clockHrs, sortOrder: state.sortedInfo.columnKey === "clockHrs" && state.sortedInfo.order, render: (text, record) => record.clockHrs.toFixed(2), }, { title: t("general.labels.actions"), dataIndex: "actions", key: "actions", render: (text, record) => ( ), }, ]; const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); }; return ( ); }; const ShiftRelatedTicketsTable = ({ loading, shiftTickets, startDate, endDate, }) => { const Templates = TemplateList(); const { t } = useTranslation(); const [state, setState] = useState({ sortedInfo: {}, }); const data = useMemo(() => { return shiftTickets.map((item) => { const clockHrs = item.tickets.reduce((acc, val) => { if (!!val.clockoff && !!val.clockon) return ( acc + moment(val.clockoff).diff(moment(val.clockon), "hours", true) ); return acc; }, 0); return { id: item.employee.id, item, clockHrs }; }); }, [shiftTickets]); const columns = [ { title: t("employees.labels.name"), dataIndex: "empname", key: "empname", sorter: (a, b) => alphaSort(a.empname, b.empname), sortOrder: state.sortedInfo.columnKey === "empname" && state.sortedInfo.order, render: (text, record) => `${record.item.employee.first_name} ${record.item.employee.last_name}`, }, { title: t("timetickets.fields.clockhours"), dataIndex: "clockHrs", key: "clockHrs", sorter: (a, b) => a.clockHrs - b.clockHrs, sortOrder: state.sortedInfo.columnKey === "clockHrs" && state.sortedInfo.order, render: (text, record) => record.clockHrs.toFixed(2), }, { title: t("general.labels.actions"), dataIndex: "actions", key: "actions", render: (text, record) => ( ), }, ]; const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); }; return (
); };