202 lines
7.0 KiB
JavaScript
202 lines
7.0 KiB
JavaScript
import React, { useEffect, useMemo, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { FlatList, RefreshControl, StyleSheet, Text, View } from "react-native";
|
|
import _ from "lodash";
|
|
import { Card, DataTable, Divider } from "react-native-paper";
|
|
import { GET_LINE_TICKET_BY_PK } from "../../graphql/jobs.queries";
|
|
import ErrorDisplay from "../error-display/error-display.component";
|
|
import { useQuery } from "@apollo/client";
|
|
import { connect } from "react-redux";
|
|
import { createStructuredSelector } from "reselect";
|
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
|
import { selectCurrentEmployee } from "../../redux/employee/employee.selectors";
|
|
import { CalculateAllocationsTotals } from "../../util/labor-allocations-table.utility";
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
bodyshop: selectBodyshop,
|
|
technician: selectCurrentEmployee,
|
|
});
|
|
|
|
export function LaborAllocationsTable({ jobId, bodyshop, technician,costCenterDiff,selectedCostCenter}) {
|
|
// console.log("LaborAllocationsTable, costCenterDiff", costCenterDiff);
|
|
// console.log("LaborAllocationsTable, selectedCostCenter", selectedCostCenter);
|
|
const { t } = useTranslation();
|
|
|
|
const onRefresh = async () => {
|
|
// console.log("LaborAllocationsTable refetch");
|
|
return refetch();
|
|
};
|
|
|
|
const { loading, error, data, refetch } = useQuery(GET_LINE_TICKET_BY_PK, {
|
|
variables: { id: jobId },
|
|
skip: !!!jobId,
|
|
fetchPolicy: "network-only",
|
|
nextFetchPolicy: "network-only",
|
|
});
|
|
// console.log("LaborAllocationsTable, data", data);
|
|
if (error) return <ErrorDisplay errorMessage={error.message} />;
|
|
|
|
const [totals, setTotals] = useState([]);
|
|
|
|
useEffect(() => {
|
|
// console.log("LaborAllocationsTable useEffect on data change");
|
|
}, [data]);
|
|
|
|
useEffect(() => {
|
|
// console.log("LaborAllocationsTable useEffect on [all inputs] change",data?.joblines,data?.adjustments);
|
|
if (!!data?.joblines && !!data?.timetickets && !!bodyshop){
|
|
let temptotals = CalculateAllocationsTotals(
|
|
bodyshop,
|
|
data?.joblines,
|
|
data?.timetickets,
|
|
data?.adjustments
|
|
);
|
|
if(!!selectedCostCenter){
|
|
let tempCostCenterDiff = Math.round(
|
|
temptotals.find(
|
|
(total) =>
|
|
total["cost_center"] === selectedCostCenter.label
|
|
)?.difference * 10
|
|
) / 10;
|
|
costCenterDiff.current= tempCostCenterDiff;
|
|
}
|
|
setTotals(
|
|
temptotals
|
|
);
|
|
}
|
|
if (!jobId) setTotals([]);
|
|
}, [data?.joblines, data?.timetickets, bodyshop, data?.adjustments, jobId,selectedCostCenter]);
|
|
|
|
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 }
|
|
);
|
|
// console.log("labor summary is:", summary);
|
|
|
|
return (
|
|
<View style={{ flex: 1}}>
|
|
{typeof data !== "undefined" ? (
|
|
<Card style={{ flex: 1 }}>
|
|
<Card.Title><Text>Labor Allocations</Text></Card.Title>
|
|
<Card.Content>
|
|
<DataTable>
|
|
<View style={localStyles.headerArea}>
|
|
<Text style={localStyles.headertext}>Cost Center</Text>
|
|
<Text style={localStyles.headertext}>Hours Total</Text>
|
|
<Text style={localStyles.headertext}>Hours Claimed</Text>
|
|
{/* <Text numberOfLines={2} style={{ flex: 1, flexWrap:'wrap' }}>Hours Claimed</Text> */}
|
|
<Text style={localStyles.headertextAdjusts}>Adjustments</Text>
|
|
<Text style={localStyles.headertext}>Difference</Text>
|
|
</View>
|
|
<Divider orientation="vertical" />
|
|
</DataTable>
|
|
<DataTable>
|
|
<FlatList
|
|
data={totals}
|
|
keyExtractor={(item) => item.cost_center}
|
|
ItemSeparatorComponent={<Divider orientation="vertical" />}
|
|
renderItem={(object) => (
|
|
<DataTable.Row style={{ flex: 1, justifyContent:"space-evenly" }}>
|
|
<View style={{ flex: 1, alignItems: "flex-start" }}>
|
|
<Text>
|
|
{object.item.cost_center} {" ("}
|
|
{object.item.mod_lbr_ty}
|
|
{")"}
|
|
</Text>
|
|
</View>
|
|
<View style={{ flex: 1, alignItems: "center" }}>
|
|
<Text>
|
|
{object.item.total && object.item.total.toFixed(1)}
|
|
</Text>
|
|
</View>
|
|
<View style={{ flex: 1, alignItems: "center" }}>
|
|
<Text>
|
|
{object.item.claimed && object.item.claimed.toFixed(1)}
|
|
</Text>
|
|
</View>
|
|
<View style={{ flex: 1, alignItems: "center" }}>
|
|
<Text>
|
|
{object.item.adjustments &&
|
|
object.item.adjustments.toFixed(1)}
|
|
</Text>
|
|
</View>
|
|
<View style={{ flex: 1, alignItems: "center" }}>
|
|
<Text
|
|
style={{
|
|
color: object.item.difference >= 0 ? "green" : "red",
|
|
}}
|
|
>
|
|
{_.round(object.item.difference, 1)}
|
|
</Text>
|
|
</View>
|
|
</DataTable.Row>
|
|
)}
|
|
/>
|
|
{summary && (
|
|
<View style={localStyles.headerArea}>
|
|
<Text style={localStyles.footertext}>Totals</Text>
|
|
<Text style={localStyles.footertext}>
|
|
{summary.hrs_total.toFixed(1)}
|
|
</Text>
|
|
<Text style={localStyles.footertext}>
|
|
{summary.hrs_claimed.toFixed(1)}
|
|
</Text>
|
|
<Text style={localStyles.footertext}>
|
|
{summary.adjustments.toFixed(1)}
|
|
</Text>
|
|
<Text style={localStyles.footertext}>
|
|
{summary.difference.toFixed(1)}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
</DataTable>
|
|
</Card.Content>
|
|
|
|
</Card>
|
|
) : null}
|
|
{/* use "totals" for the rows in the table */}
|
|
{/* use "summary" for the totals at the bottom */}
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const localStyles = StyleSheet.create({
|
|
headerArea: {
|
|
flexDirection: "row",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
margin: 1,
|
|
},
|
|
footertext: {
|
|
flex: 1,
|
|
textAlign: "center",
|
|
textAlignVertical: "center",
|
|
margin: 1,
|
|
paddingBottom: 8,
|
|
},
|
|
headertext: {
|
|
flex: 1,
|
|
textAlign: "center",
|
|
textAlignVertical: "center",
|
|
margin: 1,
|
|
paddingBottom: 8,
|
|
},
|
|
headertextAdjusts: {
|
|
flex: 1,
|
|
textAlign: "center",
|
|
textAlignVertical: "center",
|
|
margin: 1,
|
|
paddingBottom: 8,
|
|
},
|
|
});
|
|
|
|
export default connect(mapStateToProps, null)(LaborAllocationsTable);
|