added labor allocationtable
This commit is contained in:
@@ -77,12 +77,13 @@ export default connect(null, null)(CostCenterSelect);
|
|||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
padding: 16,
|
marginVertical: 4,
|
||||||
|
marginHorizontal: 16,
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignContent: "center",
|
alignContent: "center",
|
||||||
},
|
},
|
||||||
dropdown: {
|
dropdown: {
|
||||||
height: 50,
|
height: 48,
|
||||||
borderColor: "gray",
|
borderColor: "gray",
|
||||||
borderWidth: 0.5,
|
borderWidth: 0.5,
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
|
|||||||
@@ -1,23 +1,183 @@
|
|||||||
import React from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FlatList, RefreshControl, StyleSheet, Text, View } from "react-native";
|
import { FlatList, RefreshControl, StyleSheet, Text, View } from "react-native";
|
||||||
|
import _ from "lodash";
|
||||||
import { Card, DataTable } from "react-native-paper";
|
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 mapStateToProps = createStructuredSelector({
|
||||||
const { t } = useTranslation();
|
bodyshop: selectBodyshop,
|
||||||
|
technician: selectCurrentEmployee,
|
||||||
|
});
|
||||||
|
|
||||||
if (!job) {
|
export function LaborAllocationsTable({ jobId, bodyshop, technician }) {
|
||||||
<Card>
|
console.log("LaborAllocationsTable, jobId", jobId);
|
||||||
<Text>Job is not defined.</Text>
|
//, loading, refetch
|
||||||
</Card>;
|
//const jobid = jobid !== undefined ? jobid : "";
|
||||||
}
|
const { t } = useTranslation();
|
||||||
const onRefresh = async () => {
|
|
||||||
return refetch();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
const onRefresh = async () => {
|
||||||
<View style={{ flex: 1 }}>
|
|
||||||
<DataTable>
|
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.Header>
|
||||||
<DataTable.Title style={{ flex: 4 }}>
|
<DataTable.Title style={{ flex: 4 }}>
|
||||||
{t("jobdetail.labels.lines_desc")}
|
{t("jobdetail.labels.lines_desc")}
|
||||||
@@ -35,9 +195,9 @@ export default function LaborAllocationsTable({ job, loading, refetch }) {
|
|||||||
{t("jobdetail.labels.lines_qty")}
|
{t("jobdetail.labels.lines_qty")}
|
||||||
</DataTable.Title>
|
</DataTable.Title>
|
||||||
</DataTable.Header>
|
</DataTable.Header>
|
||||||
</DataTable>
|
</DataTable> */}
|
||||||
|
|
||||||
<FlatList
|
{/* <FlatList
|
||||||
data={job.joblines}
|
data={job.joblines}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||||
@@ -64,10 +224,13 @@ export default function LaborAllocationsTable({ job, loading, refetch }) {
|
|||||||
</DataTable.Cell>
|
</DataTable.Cell>
|
||||||
</DataTable.Row>
|
</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";
|
} from "../../redux/employee/employee.selectors";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { useCallback } from "react";
|
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
|
//TODO add props needed for call
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
@@ -34,15 +36,15 @@ export function TimeTicketCreate({
|
|||||||
const [date2, setDate2] = useState(new Date());
|
const [date2, setDate2] = useState(new Date());
|
||||||
|
|
||||||
const [currentSCC, setCurrentSCC] = useState(null);
|
const [currentSCC, setCurrentSCC] = useState(null);
|
||||||
const [currentSJob, setCurrentSJob] = useState(null);
|
// const [currentSJob, setCurrentSJob] = useState(null);
|
||||||
const [currentSJobId, setCurrentSJobId] = useState(null);
|
const [currentSJobId, setCurrentSJobId] = useState(null);
|
||||||
|
|
||||||
const wrapperSetCurrentSJobState = useCallback(
|
// const wrapperSetCurrentSJobState = useCallback(
|
||||||
(val) => {
|
// (val) => {
|
||||||
setCurrentSJob(val);
|
// setCurrentSJob(val);
|
||||||
},
|
// },
|
||||||
[setCurrentSJob]
|
// [setCurrentSJob]
|
||||||
);
|
// );
|
||||||
|
|
||||||
const showDatePicker = () => {
|
const showDatePicker = () => {
|
||||||
setDatePickerVisibility(true);
|
setDatePickerVisibility(true);
|
||||||
@@ -56,19 +58,20 @@ export function TimeTicketCreate({
|
|||||||
hideDatePicker();
|
hideDatePicker();
|
||||||
};
|
};
|
||||||
const formSubmit = (values) => {
|
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
|
//TODO update with start call for create time ticket
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={localStyles.content}>
|
<View style={localStyles.content}>
|
||||||
<ScrollView>
|
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
jobid: "",
|
jobid: {currentSJobId},
|
||||||
ticketdate: date2.toLocaleDateString(),
|
ticketdate: date2.toLocaleDateString(),
|
||||||
employee: currentEmployee.technician.first_name,
|
employee: currentEmployee.technician.first_name,
|
||||||
costcenter: "",
|
costcenter: {currentSCC},
|
||||||
productivehours: "",
|
productivehours: "",
|
||||||
actualhours: "",
|
actualhours: "",
|
||||||
}}
|
}}
|
||||||
@@ -146,8 +149,13 @@ export function TimeTicketCreate({
|
|||||||
</Formik>
|
</Formik>
|
||||||
|
|
||||||
{/* Below is for list of jobs/tickets */}
|
{/* Below is for list of jobs/tickets */}
|
||||||
<View style={localStyles.bottomTimeTicketContainer}></View>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
<View style={{ flexGrow: 1 }}>
|
||||||
|
|
||||||
|
<LaborAllocationsTable jobId={currentSJobId?.value} />
|
||||||
|
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -159,12 +167,13 @@ const localStyles = StyleSheet.create({
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
topTimeTicketContainer: {},
|
topContainer: {},
|
||||||
bottomTimeTicketContainer: {},
|
bottomContainer: {},
|
||||||
input: {},
|
input: {},
|
||||||
dateButton: {
|
dateButton: {
|
||||||
margin: 16,
|
marginVertical: 4,
|
||||||
height: 40,
|
marginHorizontal: 16,
|
||||||
|
height: 48,
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignContent: "center",
|
alignContent: "center",
|
||||||
borderColor: "blue",
|
borderColor: "blue",
|
||||||
@@ -177,7 +186,8 @@ const localStyles = StyleSheet.create({
|
|||||||
alignContent: "center",
|
alignContent: "center",
|
||||||
},
|
},
|
||||||
inputStyle: {
|
inputStyle: {
|
||||||
margin: 16,
|
marginVertical: 4,
|
||||||
|
marginHorizontal: 16,
|
||||||
height: 48,
|
height: 48,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -923,6 +923,54 @@ export const QUERY_JOB_CLOSE_DETAILS = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const GET_LINE_TICKET_BY_PK = gql`
|
||||||
|
query GET_LINE_TICKET_BY_PK($id: uuid!) {
|
||||||
|
jobs_by_pk(id: $id) {
|
||||||
|
id
|
||||||
|
lbr_adjustments
|
||||||
|
converted
|
||||||
|
}
|
||||||
|
joblines(where: { jobid: { _eq: $id }, removed: { _eq: false } }) {
|
||||||
|
id
|
||||||
|
line_desc
|
||||||
|
part_type
|
||||||
|
oem_partno
|
||||||
|
db_price
|
||||||
|
act_price
|
||||||
|
part_qty
|
||||||
|
mod_lbr_ty
|
||||||
|
db_hrs
|
||||||
|
mod_lb_hrs
|
||||||
|
lbr_op
|
||||||
|
lbr_amt
|
||||||
|
op_code_desc
|
||||||
|
convertedtolbr
|
||||||
|
convertedtolbr_data
|
||||||
|
}
|
||||||
|
timetickets(where: { jobid: { _eq: $id } }) {
|
||||||
|
actualhrs
|
||||||
|
ciecacode
|
||||||
|
cost_center
|
||||||
|
date
|
||||||
|
id
|
||||||
|
jobid
|
||||||
|
employeeid
|
||||||
|
memo
|
||||||
|
flat_rate
|
||||||
|
clockon
|
||||||
|
clockoff
|
||||||
|
rate
|
||||||
|
employee {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
employee_number
|
||||||
|
}
|
||||||
|
productivehrs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const generate_UPDATE_JOB_KANBAN = (
|
export const generate_UPDATE_JOB_KANBAN = (
|
||||||
oldChildId,
|
oldChildId,
|
||||||
oldChildNewParent,
|
oldChildNewParent,
|
||||||
|
|||||||
@@ -360,6 +360,96 @@
|
|||||||
"titles": {
|
"titles": {
|
||||||
"createtimeticket": "Create a Time Ticket"
|
"createtimeticket": "Create a Time Ticket"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"joblines": {
|
||||||
|
"actions": {
|
||||||
|
"converttolabor": "Convert amount to Labor.",
|
||||||
|
"new": "New Line"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"creating": "Error encountered while creating job line. {{message}}",
|
||||||
|
"updating": "Error encountered updating job line. {{message}}"
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"act_price": "Retail Price",
|
||||||
|
"ah_detail_line": "Mark as Detail Labor Line (Autohouse Only)",
|
||||||
|
"db_price": "List Price",
|
||||||
|
"lbr_types": {
|
||||||
|
"LA1": "LA1",
|
||||||
|
"LA2": "LA2",
|
||||||
|
"LA3": "LA3",
|
||||||
|
"LA4": "LA4",
|
||||||
|
"LAA": "Aluminum",
|
||||||
|
"LAB": "Body",
|
||||||
|
"LAD": "Diagnostic",
|
||||||
|
"LAE": "Electrical",
|
||||||
|
"LAF": "Frame",
|
||||||
|
"LAG": "Glass",
|
||||||
|
"LAM": "Mechanical",
|
||||||
|
"LAR": "Refinish",
|
||||||
|
"LAS": "Structural",
|
||||||
|
"LAU": "User Defined"
|
||||||
|
},
|
||||||
|
"line_desc": "Line Desc.",
|
||||||
|
"line_ind": "S#",
|
||||||
|
"line_no": "Line #",
|
||||||
|
"location": "Location",
|
||||||
|
"mod_lb_hrs": "Hrs",
|
||||||
|
"mod_lbr_ty": "Labor Type",
|
||||||
|
"notes": "Notes",
|
||||||
|
"oem_partno": "OEM Part #",
|
||||||
|
"op_code_desc": "Op Code Description",
|
||||||
|
"part_qty": "Qty.",
|
||||||
|
"part_type": "Part Type",
|
||||||
|
"part_types": {
|
||||||
|
"CCC": "CC Cleaning",
|
||||||
|
"CCD": "CC Damage Waiver",
|
||||||
|
"CCDR": "CC Daily Rate",
|
||||||
|
"CCF": "CC Refuel",
|
||||||
|
"CCM": "CC Mileage",
|
||||||
|
"PAA": "Aftermarket",
|
||||||
|
"PAC": "Rechromed",
|
||||||
|
"PAE": "Existing",
|
||||||
|
"PAG": "Glass",
|
||||||
|
"PAL": "LKQ",
|
||||||
|
"PAM": "Remanufactured",
|
||||||
|
"PAN": "New/OEM",
|
||||||
|
"PAO": "Other",
|
||||||
|
"PAP": "OEM Partial",
|
||||||
|
"PAR": "Recored",
|
||||||
|
"PAS": "Sublet",
|
||||||
|
"PASL": "Sublet (L)"
|
||||||
|
},
|
||||||
|
"profitcenter_labor": "Profit Center: Labor",
|
||||||
|
"profitcenter_part": "Profit Center: Part",
|
||||||
|
"prt_dsmk_m": "Line Discount/Markup $",
|
||||||
|
"prt_dsmk_p": "Line Discount/Markup %",
|
||||||
|
"status": "Status",
|
||||||
|
"tax_part": "Tax Part",
|
||||||
|
"total": "Total",
|
||||||
|
"unq_seq": "Seq #"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"adjustmenttobeadded": "Adjustment to be added: {{adjustment}}",
|
||||||
|
"billref": "Latest Bill",
|
||||||
|
"convertedtolabor": "This line has been converted to labor. Ensure you adjust the profit center for the amount accordingly.",
|
||||||
|
"edit": "Edit Line",
|
||||||
|
"ioucreated": "IOU",
|
||||||
|
"new": "New Line",
|
||||||
|
"nostatus": "No Status",
|
||||||
|
"presets": "Jobline Presets"
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"created": "Job line created successfully.",
|
||||||
|
"saved": "Job line saved.",
|
||||||
|
"updated": "Job line updated successfully."
|
||||||
|
},
|
||||||
|
"validations": {
|
||||||
|
"ahdetailonlyonuserdefinedtypes": "Detail line indicator can only be set for LA1, LA2, LA3, LA4, and LAU labor types.",
|
||||||
|
"hrsrequirediflbrtyp": "Labor hours are required if a labor type is selected. Clear the labor type if there are no labor hours.",
|
||||||
|
"requiredifparttype": "Required if a part type has been specified.",
|
||||||
|
"zeropriceexistingpart": "This line cannot have any price since it uses an existing part."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,6 +360,96 @@
|
|||||||
"titles": {
|
"titles": {
|
||||||
"createtimeticket": ""
|
"createtimeticket": ""
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"joblines": {
|
||||||
|
"actions": {
|
||||||
|
"converttolabor": "",
|
||||||
|
"new": ""
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"creating": "",
|
||||||
|
"updating": ""
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"act_price": "Precio actual",
|
||||||
|
"ah_detail_line": "",
|
||||||
|
"db_price": "Precio de base de datos",
|
||||||
|
"lbr_types": {
|
||||||
|
"LA1": "",
|
||||||
|
"LA2": "",
|
||||||
|
"LA3": "",
|
||||||
|
"LA4": "",
|
||||||
|
"LAA": "",
|
||||||
|
"LAB": "",
|
||||||
|
"LAD": "",
|
||||||
|
"LAE": "",
|
||||||
|
"LAF": "",
|
||||||
|
"LAG": "",
|
||||||
|
"LAM": "",
|
||||||
|
"LAR": "",
|
||||||
|
"LAS": "",
|
||||||
|
"LAU": ""
|
||||||
|
},
|
||||||
|
"line_desc": "Descripción de línea",
|
||||||
|
"line_ind": "S#",
|
||||||
|
"line_no": "",
|
||||||
|
"location": "",
|
||||||
|
"mod_lb_hrs": "Horas laborales",
|
||||||
|
"mod_lbr_ty": "Tipo de trabajo",
|
||||||
|
"notes": "",
|
||||||
|
"oem_partno": "OEM parte #",
|
||||||
|
"op_code_desc": "",
|
||||||
|
"part_qty": "",
|
||||||
|
"part_type": "Tipo de parte",
|
||||||
|
"part_types": {
|
||||||
|
"CCC": "",
|
||||||
|
"CCD": "",
|
||||||
|
"CCDR": "",
|
||||||
|
"CCF": "",
|
||||||
|
"CCM": "",
|
||||||
|
"PAA": "",
|
||||||
|
"PAC": "",
|
||||||
|
"PAE": "",
|
||||||
|
"PAG": "",
|
||||||
|
"PAL": "",
|
||||||
|
"PAM": "",
|
||||||
|
"PAN": "",
|
||||||
|
"PAO": "",
|
||||||
|
"PAP": "",
|
||||||
|
"PAR": "",
|
||||||
|
"PAS": "",
|
||||||
|
"PASL": ""
|
||||||
|
},
|
||||||
|
"profitcenter_labor": "",
|
||||||
|
"profitcenter_part": "",
|
||||||
|
"prt_dsmk_m": "",
|
||||||
|
"prt_dsmk_p": "",
|
||||||
|
"status": "Estado",
|
||||||
|
"tax_part": "",
|
||||||
|
"total": "",
|
||||||
|
"unq_seq": "Seq #"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"adjustmenttobeadded": "",
|
||||||
|
"billref": "",
|
||||||
|
"convertedtolabor": "",
|
||||||
|
"edit": "Línea de edición",
|
||||||
|
"ioucreated": "",
|
||||||
|
"new": "Nueva línea",
|
||||||
|
"nostatus": "",
|
||||||
|
"presets": ""
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"created": "",
|
||||||
|
"saved": "",
|
||||||
|
"updated": ""
|
||||||
|
},
|
||||||
|
"validations": {
|
||||||
|
"ahdetailonlyonuserdefinedtypes": "",
|
||||||
|
"hrsrequirediflbrtyp": "",
|
||||||
|
"requiredifparttype": "",
|
||||||
|
"zeropriceexistingpart": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,6 +360,96 @@
|
|||||||
"titles": {
|
"titles": {
|
||||||
"createtimeticket": ""
|
"createtimeticket": ""
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"joblines": {
|
||||||
|
"actions": {
|
||||||
|
"converttolabor": "",
|
||||||
|
"new": ""
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"creating": "",
|
||||||
|
"updating": ""
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"act_price": "Prix actuel",
|
||||||
|
"ah_detail_line": "",
|
||||||
|
"db_price": "Prix de la base de données",
|
||||||
|
"lbr_types": {
|
||||||
|
"LA1": "",
|
||||||
|
"LA2": "",
|
||||||
|
"LA3": "",
|
||||||
|
"LA4": "",
|
||||||
|
"LAA": "",
|
||||||
|
"LAB": "",
|
||||||
|
"LAD": "",
|
||||||
|
"LAE": "",
|
||||||
|
"LAF": "",
|
||||||
|
"LAG": "",
|
||||||
|
"LAM": "",
|
||||||
|
"LAR": "",
|
||||||
|
"LAS": "",
|
||||||
|
"LAU": ""
|
||||||
|
},
|
||||||
|
"line_desc": "Description de la ligne",
|
||||||
|
"line_ind": "S#",
|
||||||
|
"line_no": "",
|
||||||
|
"location": "",
|
||||||
|
"mod_lb_hrs": "Heures de travail",
|
||||||
|
"mod_lbr_ty": "Type de travail",
|
||||||
|
"notes": "",
|
||||||
|
"oem_partno": "Pièce OEM #",
|
||||||
|
"op_code_desc": "",
|
||||||
|
"part_qty": "",
|
||||||
|
"part_type": "Type de pièce",
|
||||||
|
"part_types": {
|
||||||
|
"CCC": "",
|
||||||
|
"CCD": "",
|
||||||
|
"CCDR": "",
|
||||||
|
"CCF": "",
|
||||||
|
"CCM": "",
|
||||||
|
"PAA": "",
|
||||||
|
"PAC": "",
|
||||||
|
"PAE": "",
|
||||||
|
"PAG": "",
|
||||||
|
"PAL": "",
|
||||||
|
"PAM": "",
|
||||||
|
"PAN": "",
|
||||||
|
"PAO": "",
|
||||||
|
"PAP": "",
|
||||||
|
"PAR": "",
|
||||||
|
"PAS": "",
|
||||||
|
"PASL": ""
|
||||||
|
},
|
||||||
|
"profitcenter_labor": "",
|
||||||
|
"profitcenter_part": "",
|
||||||
|
"prt_dsmk_m": "",
|
||||||
|
"prt_dsmk_p": "",
|
||||||
|
"status": "Statut",
|
||||||
|
"tax_part": "",
|
||||||
|
"total": "",
|
||||||
|
"unq_seq": "Seq #"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"adjustmenttobeadded": "",
|
||||||
|
"billref": "",
|
||||||
|
"convertedtolabor": "",
|
||||||
|
"edit": "Ligne d'édition",
|
||||||
|
"ioucreated": "",
|
||||||
|
"new": "Nouvelle ligne",
|
||||||
|
"nostatus": "",
|
||||||
|
"presets": ""
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"created": "",
|
||||||
|
"saved": "",
|
||||||
|
"updated": ""
|
||||||
|
},
|
||||||
|
"validations": {
|
||||||
|
"ahdetailonlyonuserdefinedtypes": "",
|
||||||
|
"hrsrequirediflbrtyp": "",
|
||||||
|
"requiredifparttype": "",
|
||||||
|
"zeropriceexistingpart": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
util/labor-allocations-table.utility.js
Normal file
54
util/labor-allocations-table.utility.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import i18next from "i18next";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const CalculateAllocationsTotals = (
|
||||||
|
bodyshop,
|
||||||
|
joblines,
|
||||||
|
timetickets,
|
||||||
|
adjustments = []
|
||||||
|
) => {
|
||||||
|
// console.log("🚀 ~ file: adjustments", adjustments);
|
||||||
|
// console.log("🚀 ~ file: bodyshop", bodyshop);
|
||||||
|
console.log("🚀 ~ file: joblines", joblines);
|
||||||
|
// console.log("🚀 ~ file: timetickets", timetickets);
|
||||||
|
const responsibilitycenters = bodyshop.md_responsibility_centers;
|
||||||
|
const jobCodes = joblines.map((item) => item.mod_lbr_ty);
|
||||||
|
console.log("jobCodes :", jobCodes);
|
||||||
|
//.filter((value, index, self) => self.indexOf(value) === index && !!value);
|
||||||
|
const ticketCodes = timetickets.map((item) => item.ciecacode);
|
||||||
|
console.log("ticketCodes :", ticketCodes);
|
||||||
|
//.filter((value, index, self) => self.indexOf(value) === index && !!value);
|
||||||
|
const adjustmentCodes = Object.keys(adjustments);
|
||||||
|
console.log("adjustmentCodes :", adjustmentCodes);
|
||||||
|
const allCodes = [...jobCodes, ...ticketCodes, ...adjustmentCodes].filter(
|
||||||
|
(value, index, self) => self.indexOf(value) === index && !!value
|
||||||
|
);
|
||||||
|
console.log("allCodes :", allCodes);
|
||||||
|
|
||||||
|
const r = allCodes.reduce((acc, value) => {
|
||||||
|
const r = {
|
||||||
|
opcode: value,
|
||||||
|
cost_center:
|
||||||
|
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
|
||||||
|
? i18next.t(
|
||||||
|
`joblines.fields.lbr_types.${value && value.toUpperCase()}`
|
||||||
|
)
|
||||||
|
: responsibilitycenters.defaults.costs[value],
|
||||||
|
mod_lbr_ty: value,
|
||||||
|
total: joblines.reduce((acc2, val2) => {
|
||||||
|
return val2.mod_lbr_ty === value ? acc2 + val2.mod_lb_hrs : acc2;
|
||||||
|
}, 0),
|
||||||
|
adjustments: adjustments[value] || 0,
|
||||||
|
claimed: timetickets.reduce((acc3, val3) => {
|
||||||
|
return val3.ciecacode === value ? acc3 + val3.productivehrs : acc3;
|
||||||
|
}, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
r.difference = r.total + r.adjustments - r.claimed;
|
||||||
|
acc.push(r);
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
console.log(" r is :", r);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user