From d9e2ef9300cfeec06e20936a298e7a7c84a7c8ab Mon Sep 17 00:00:00 2001 From: swtmply Date: Thu, 27 Apr 2023 22:19:32 +0800 Subject: [PATCH] IO-1933 Added statistics on tech page --- .../scoreboard-timetickets.component.jsx | 8 +- ...scoreboard-timetickets.stats.component.jsx | 2 +- .../tech-job-statistics.component.jsx | 136 ++++++++++++++++++ client/src/graphql/timetickets.queries.js | 75 ++++++++++ .../tech-job-clock.component.jsx | 2 + 5 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 client/src/components/tech-job-statistics/tech-job-statistics.component.jsx diff --git a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx index 138e54228..0fc84af6d 100644 --- a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx +++ b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx @@ -241,9 +241,11 @@ export default function ScoreboardTimeTickets() { ); ret.totalEffieciencyOverPeriod = - (totalActualAndProductive.totalOverPeriod / - totalActualAndProductive.actualTotalOverPeriod) * - 100; + totalActualAndProductive.actualTotalOverPeriod + ? (totalActualAndProductive.totalOverPeriod / + totalActualAndProductive.actualTotalOverPeriod) * + 100 + : 0; roundObject(ret); roundObject(totals); diff --git a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx index e31cec3af..40f3ed32c 100644 --- a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx +++ b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx @@ -116,7 +116,7 @@ export function ScoreboardTicketsStats({ data, bodyshop }) { diff --git a/client/src/components/tech-job-statistics/tech-job-statistics.component.jsx b/client/src/components/tech-job-statistics/tech-job-statistics.component.jsx new file mode 100644 index 000000000..ec26a8069 --- /dev/null +++ b/client/src/components/tech-job-statistics/tech-job-statistics.component.jsx @@ -0,0 +1,136 @@ +import { Card, Col, Space, Statistic, Typography } from "antd"; +import { useLocation } from "react-router-dom"; +import queryString from "query-string"; +import moment from "moment"; +import { useQuery } from "@apollo/client"; +import { QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE } from "../../graphql/timetickets.queries"; +import { createStructuredSelector } from "reselect"; +import { selectTechnician } from "../../redux/tech/tech.selectors"; +import { connect } from "react-redux"; +import AlertComponent from "../alert/alert.component"; +import LoadingSpinner from "../loading-spinner/loading-spinner.component"; +import { useMemo } from "react"; + +const { Title } = Typography; + +const mapStateToProps = createStructuredSelector({ + technician: selectTechnician, +}); +const mapDispatchToProps = (dispatch) => ({}); + +const TechJobStatistics = ({ technician }) => { + const searchParams = queryString.parse(useLocation().search); + const { start, end } = searchParams; + + const startDate = start + ? moment(start) + : moment().startOf("week").subtract(7, "days"); + const endDate = end ? moment(end) : moment().endOf("week"); + + const { loading, error, data } = useQuery( + QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE, + { + variables: { + start: startDate.format("YYYY-MM-DD"), + end: endDate.format("YYYY-MM-DD"), + fixedStart: moment().startOf("month").format("YYYY-MM-DD"), + fixedEnd: moment().endOf("month").format("YYYY-MM-DD"), + employeeid: technician.id, + }, + fetchPolicy: "network-only", + nextFetchPolicy: "network-only", + } + ); + + const totals = useMemo(() => { + if (data && data.timetickets && data.fixedperiod) { + const week = data.timetickets.reduce( + (acc, val) => { + acc.productivehrs = acc.productivehrs + val.productivehrs; + acc.actualhrs = acc.actualhrs + val.actualhrs; + return acc; + }, + { productivehrs: 0, actualhrs: 0 } + ); + + const month = data.fixedperiod.reduce( + (acc, val) => { + acc.productivehrs = acc.productivehrs + val.productivehrs; + acc.actualhrs = acc.actualhrs + val.actualhrs; + return acc; + }, + { productivehrs: 0, actualhrs: 0 } + ); + + return { + week, + month, + }; + } + + return { + week: { productivehrs: 0, actualhrs: 0 }, + month: { productivehrs: 0, actualhrs: 0 }, + }; + }, [data]); + + if (loading) return ; + if (error) return ; + + return ( + + + + This Week + + + + + + + + This Month + + + + + + + + + ); +}; + +export default connect(mapStateToProps, mapDispatchToProps)(TechJobStatistics); diff --git a/client/src/graphql/timetickets.queries.js b/client/src/graphql/timetickets.queries.js index fd593a003..e6f04868f 100644 --- a/client/src/graphql/timetickets.queries.js +++ b/client/src/graphql/timetickets.queries.js @@ -59,6 +59,81 @@ export const QUERY_TIME_TICKETS_IN_RANGE = gql` } `; +export const QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE = gql` + query QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE( + $employeeid: uuid! + $start: date! + $end: date! + $fixedStart: date! + $fixedEnd: date! + ) { + timetickets( + where: { + date: { _gte: $start, _lte: $end } + employeeid: { _eq: $employeeid } + } + order_by: { date: desc_nulls_first } + ) { + actualhrs + ciecacode + clockoff + clockon + cost_center + created_at + date + id + rate + productivehrs + memo + jobid + flat_rate + job { + id + ro_number + } + employeeid + employee { + id + employee_number + first_name + last_name + } + } + fixedperiod: timetickets( + where: { + date: { _gte: $fixedStart, _lte: $fixedEnd } + employeeid: { _eq: $employeeid } + } + order_by: { date: desc_nulls_first } + ) { + actualhrs + ciecacode + clockoff + clockon + cost_center + created_at + date + id + rate + productivehrs + memo + jobid + flat_rate + job { + id + ro_number + } + employeeid + employee { + id + employee_number + first_name + last_name + } + } + } +`; + export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql` query QUERY_TIME_TICKETS_IN_RANGE_SB( $start: date! diff --git a/client/src/pages/tech-job-clock/tech-job-clock.component.jsx b/client/src/pages/tech-job-clock/tech-job-clock.component.jsx index 092510b02..0d64068eb 100644 --- a/client/src/pages/tech-job-clock/tech-job-clock.component.jsx +++ b/client/src/pages/tech-job-clock/tech-job-clock.component.jsx @@ -2,10 +2,12 @@ import { Divider } from "antd"; import React from "react"; import TechClockInFormContainer from "../../components/tech-job-clock-in-form/tech-job-clock-in-form.container"; import TechClockedInList from "../../components/tech-job-clocked-in-list/tech-job-clocked-in-list.component"; +import TechJobStatistics from "../../components/tech-job-statistics/tech-job-statistics.component"; export default function TechClockComponent() { return (
+