added labor allocationtable
This commit is contained in:
@@ -77,12 +77,13 @@ export default connect(null, null)(CostCenterSelect);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
padding: 16,
|
||||
marginVertical: 4,
|
||||
marginHorizontal: 16,
|
||||
justifyContent: "center",
|
||||
alignContent: "center",
|
||||
},
|
||||
dropdown: {
|
||||
height: 50,
|
||||
height: 48,
|
||||
borderColor: "gray",
|
||||
borderWidth: 0.5,
|
||||
borderRadius: 8,
|
||||
|
||||
@@ -1,23 +1,183 @@
|
||||
import React from "react";
|
||||
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 } 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";
|
||||
|
||||
export default function LaborAllocationsTable({ job, loading, refetch }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!job) {
|
||||
<Card>
|
||||
<Text>Job is not defined.</Text>
|
||||
</Card>;
|
||||
}
|
||||
const onRefresh = async () => {
|
||||
return refetch();
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<DataTable>
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
technician: selectCurrentEmployee,
|
||||
});
|
||||
|
||||
export function LaborAllocationsTable({ jobId, bodyshop, technician }) {
|
||||
console.log("LaborAllocationsTable, jobId", jobId);
|
||||
//, loading, refetch
|
||||
//const jobid = jobid !== undefined ? jobid : "";
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onRefresh = async () => {
|
||||
|
||||
console.log("LaborAllocationsTable refetch");
|
||||
return refetch();
|
||||
};
|
||||
|
||||
//maybe use this
|
||||
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} />;
|
||||
|
||||
// let joblines = [];
|
||||
// let timetickets = [];
|
||||
// let adjustments = [];
|
||||
|
||||
const [totals, setTotals] = useState([]);
|
||||
const [state, setState] = useState({
|
||||
sortedInfo: {
|
||||
columnKey: "cost_center",
|
||||
field: "cost_center",
|
||||
order: "ascend",
|
||||
},
|
||||
filteredInfo: {},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
console.log("LaborAllocationsTable useEffect on data change");
|
||||
// joblines = data?.joblines ? data.joblines : [];
|
||||
// timetickets = data?.timetickets ? data.timetickets : [];
|
||||
// adjustments = data?.adjustments ? data.adjustments : [];
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(
|
||||
"LaborAllocationsTable useEffect on [joblines, timetickets, bodyshop, adjustments, jobId] change",
|
||||
data?.joblines,
|
||||
data?.adjustments
|
||||
);
|
||||
if (!!data?.joblines && !!data?.timetickets && !!bodyshop)
|
||||
setTotals(
|
||||
CalculateAllocationsTotals(
|
||||
bodyshop,
|
||||
data?.joblines,
|
||||
data?.timetickets,
|
||||
data?.adjustments
|
||||
)
|
||||
);
|
||||
if (!jobId) setTotals([]);
|
||||
}, [data?.joblines, data?.timetickets, bodyshop, data?.adjustments, jobId]);
|
||||
|
||||
// const convertedLines = useMemo(
|
||||
// () => data?.joblines && data?.joblines.filter((j) => j.convertedtolbr),
|
||||
// [data?.joblines]
|
||||
// );
|
||||
|
||||
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={{ flexGrow: 1 }}>
|
||||
{typeof data !== "undefined" ? (
|
||||
<View style={{ flexGrow: 1 }}>
|
||||
<DataTable>
|
||||
<DataTable.Header>
|
||||
<DataTable.Title style={{ flex: 2 }}>Cost Center</DataTable.Title>
|
||||
<DataTable.Title numeric style={{ flex: 2 }}>
|
||||
Hours Total
|
||||
</DataTable.Title>
|
||||
<DataTable.Title numeric style={{ flex: 2 }}>
|
||||
Hours Claimed
|
||||
</DataTable.Title>
|
||||
<DataTable.Title numeric style={{ flex: 2 }}>
|
||||
Adjustments
|
||||
</DataTable.Title>
|
||||
<DataTable.Title numeric style={{ flex: 2 }}>
|
||||
Difference
|
||||
</DataTable.Title>
|
||||
</DataTable.Header>
|
||||
</DataTable>
|
||||
<DataTable>
|
||||
<FlatList
|
||||
data={totals}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||
}
|
||||
keyExtractor={(item) => item.cost_center}
|
||||
renderItem={(object) => (
|
||||
|
||||
<DataTable.Row>
|
||||
<DataTable.Cell style={{ flex: 2 }}>
|
||||
<Text>
|
||||
{object.item.cost_center}
|
||||
{object.item.mod_lbr_ty}
|
||||
</Text>
|
||||
</DataTable.Cell>
|
||||
<DataTable.Cell style={{ flex: 2 }}>
|
||||
<Text>{object.item.total && object.item.total.toFixed(1)}</Text>
|
||||
</DataTable.Cell>
|
||||
<DataTable.Cell style={{ flex: 2 }}>
|
||||
<Text>{object.item.claimed && object.item.claimed.toFixed(1)}</Text>
|
||||
</DataTable.Cell>
|
||||
<DataTable.Cell style={{ flex: 2 }}>
|
||||
<Text>
|
||||
{object.item.adjustments && object.item.adjustments.toFixed(1)}
|
||||
{/* {!technician && (
|
||||
<LaborAllocationsAdjustmentEdit
|
||||
jobId={jobId}
|
||||
adjustments={adjustments}
|
||||
mod_lbr_ty={record.opcode}
|
||||
refetchQueryNames={["GET_LINE_TICKET_BY_PK"]}
|
||||
>
|
||||
<EditFilled />
|
||||
</LaborAllocationsAdjustmentEdit>
|
||||
)} */}
|
||||
</Text>
|
||||
</DataTable.Cell>
|
||||
<DataTable.Cell style={{ flex: 2 }}>
|
||||
<Text style={{
|
||||
color: object.item.difference >= 0 ? "green" : "red",
|
||||
}}>
|
||||
{/* <strong
|
||||
style={{
|
||||
color: object.difference >= 0 ? "green" : "red",
|
||||
}}
|
||||
>
|
||||
{_.round(object.difference, 1)}
|
||||
</strong> */}
|
||||
{_.round(object.item.difference, 1)}
|
||||
</Text>
|
||||
</DataTable.Cell>
|
||||
</DataTable.Row>
|
||||
)}
|
||||
/>
|
||||
</DataTable>
|
||||
</View>
|
||||
) : null}
|
||||
{/* <DataTable>
|
||||
<DataTable.Header>
|
||||
<DataTable.Title style={{ flex: 4 }}>
|
||||
{t("jobdetail.labels.lines_desc")}
|
||||
@@ -35,9 +195,9 @@ export default function LaborAllocationsTable({ job, loading, refetch }) {
|
||||
{t("jobdetail.labels.lines_qty")}
|
||||
</DataTable.Title>
|
||||
</DataTable.Header>
|
||||
</DataTable>
|
||||
|
||||
<FlatList
|
||||
</DataTable> */}
|
||||
|
||||
{/* <FlatList
|
||||
data={job.joblines}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||
@@ -64,10 +224,13 @@ export default function LaborAllocationsTable({ job, loading, refetch }) {
|
||||
</DataTable.Cell>
|
||||
</DataTable.Row>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const localStyles = StyleSheet.create({});
|
||||
|
||||
/> */}
|
||||
|
||||
{/* use "totals" for the rows in the table */}
|
||||
{/* use "summary" for the totals at the bottom */}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const localStyles = StyleSheet.create({});
|
||||
export default connect(mapStateToProps, null)(LaborAllocationsTable);
|
||||
|
||||
@@ -14,6 +14,8 @@ import {
|
||||
} from "../../redux/employee/employee.selectors";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { useCallback } from "react";
|
||||
// import LaborAllocationsTable from "../labor-allocations-table/labor-allocations-table.component";
|
||||
import LaborAllocationsTable from "../labor-allocations-table/labor-allocations-table.component";
|
||||
|
||||
//TODO add props needed for call
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
@@ -34,15 +36,15 @@ export function TimeTicketCreate({
|
||||
const [date2, setDate2] = useState(new Date());
|
||||
|
||||
const [currentSCC, setCurrentSCC] = useState(null);
|
||||
const [currentSJob, setCurrentSJob] = useState(null);
|
||||
// const [currentSJob, setCurrentSJob] = useState(null);
|
||||
const [currentSJobId, setCurrentSJobId] = useState(null);
|
||||
|
||||
const wrapperSetCurrentSJobState = useCallback(
|
||||
(val) => {
|
||||
setCurrentSJob(val);
|
||||
},
|
||||
[setCurrentSJob]
|
||||
);
|
||||
// const wrapperSetCurrentSJobState = useCallback(
|
||||
// (val) => {
|
||||
// setCurrentSJob(val);
|
||||
// },
|
||||
// [setCurrentSJob]
|
||||
// );
|
||||
|
||||
const showDatePicker = () => {
|
||||
setDatePickerVisibility(true);
|
||||
@@ -56,19 +58,20 @@ export function TimeTicketCreate({
|
||||
hideDatePicker();
|
||||
};
|
||||
const formSubmit = (values) => {
|
||||
Dialog.alert({ content: <pre>{JSON.stringify(values, null, 2)}</pre> });
|
||||
console.log("values", values);
|
||||
//Dialog.alert({ content: <pre>{JSON.stringify(values, null, 2)}</pre> });
|
||||
//TODO update with start call for create time ticket
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={localStyles.content}>
|
||||
<ScrollView>
|
||||
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
|
||||
<Formik
|
||||
initialValues={{
|
||||
jobid: "",
|
||||
jobid: {currentSJobId},
|
||||
ticketdate: date2.toLocaleDateString(),
|
||||
employee: currentEmployee.technician.first_name,
|
||||
costcenter: "",
|
||||
costcenter: {currentSCC},
|
||||
productivehours: "",
|
||||
actualhours: "",
|
||||
}}
|
||||
@@ -146,8 +149,13 @@ export function TimeTicketCreate({
|
||||
</Formik>
|
||||
|
||||
{/* Below is for list of jobs/tickets */}
|
||||
<View style={localStyles.bottomTimeTicketContainer}></View>
|
||||
|
||||
</ScrollView>
|
||||
<View style={{ flexGrow: 1 }}>
|
||||
|
||||
<LaborAllocationsTable jobId={currentSJobId?.value} />
|
||||
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -159,12 +167,13 @@ const localStyles = StyleSheet.create({
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
},
|
||||
topTimeTicketContainer: {},
|
||||
bottomTimeTicketContainer: {},
|
||||
topContainer: {},
|
||||
bottomContainer: {},
|
||||
input: {},
|
||||
dateButton: {
|
||||
margin: 16,
|
||||
height: 40,
|
||||
marginVertical: 4,
|
||||
marginHorizontal: 16,
|
||||
height: 48,
|
||||
justifyContent: "center",
|
||||
alignContent: "center",
|
||||
borderColor: "blue",
|
||||
@@ -177,7 +186,8 @@ const localStyles = StyleSheet.create({
|
||||
alignContent: "center",
|
||||
},
|
||||
inputStyle: {
|
||||
margin: 16,
|
||||
marginVertical: 4,
|
||||
marginHorizontal: 16,
|
||||
height: 48,
|
||||
fontSize: 16,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user