Establish working version of pay all and labor calculations.
This commit is contained in:
@@ -88,6 +88,7 @@ export function JobsDetailLaborContainer({
|
||||
jobId={jobId}
|
||||
joblines={joblines}
|
||||
timetickets={timetickets}
|
||||
refetch={refetch}
|
||||
adjustments={adjustments}
|
||||
/>
|
||||
</Col>
|
||||
@@ -97,6 +98,7 @@ export function JobsDetailLaborContainer({
|
||||
jobId={jobId}
|
||||
joblines={joblines}
|
||||
timetickets={timetickets}
|
||||
refetch={refetch}
|
||||
adjustments={adjustments}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
@@ -13,6 +13,7 @@ import LaborAllocationsAdjustmentEdit from "../labor-allocations-adjustment-edit
|
||||
import "./labor-allocations-table.styles.scss";
|
||||
import { CalculateAllocationsTotals } from "./labor-allocations-table.utility";
|
||||
import axios from "axios";
|
||||
import { onlyUnique } from "../../utils/arrayHelper";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -26,6 +27,7 @@ export function PayrollLaborAllocationsTable({
|
||||
bodyshop,
|
||||
adjustments,
|
||||
technician,
|
||||
refetch,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [totals, setTotals] = useState([]);
|
||||
@@ -39,11 +41,16 @@ export function PayrollLaborAllocationsTable({
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!!joblines && !!timetickets && !!bodyshop);
|
||||
async function CalculateTotals() {
|
||||
const { data } = await axios.post("/payroll/calculatelabor", {
|
||||
jobid: jobId,
|
||||
});
|
||||
setTotals(data);
|
||||
}
|
||||
|
||||
setTotals(
|
||||
CalculateAllocationsTotals(bodyshop, joblines, timetickets, adjustments)
|
||||
);
|
||||
if (!!joblines && !!timetickets && !!bodyshop) {
|
||||
CalculateTotals();
|
||||
}
|
||||
if (!jobId) setTotals([]);
|
||||
}, [joblines, timetickets, bodyshop, adjustments, jobId]);
|
||||
|
||||
@@ -54,55 +61,46 @@ export function PayrollLaborAllocationsTable({
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: t("timetickets.fields.cost_center"),
|
||||
dataIndex: "cost_center",
|
||||
key: "cost_center",
|
||||
defaultSortOrder: "cost_center",
|
||||
sorter: (a, b) => alphaSort(a.cost_center, b.cost_center),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "cost_center" && state.sortedInfo.order,
|
||||
render: (text, record) => `${record.cost_center} (${record.mod_lbr_ty})`,
|
||||
title: t("timetickets.fields.employee"),
|
||||
dataIndex: "employeeid",
|
||||
key: "employeeid",
|
||||
render: (text, record) => {
|
||||
if (record.employeeid === undefined) {
|
||||
return "Unassigned";
|
||||
}
|
||||
const emp = bodyshop.employees.find((e) => e.id === record.employeeid);
|
||||
return `${emp?.first_name} ${emp?.last_name}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t("joblines.fields.mod_lbr_ty"),
|
||||
dataIndex: "mod_lbr_ty",
|
||||
key: "mod_lbr_ty",
|
||||
},
|
||||
{
|
||||
title: t("timetickets.fields.rate"),
|
||||
dataIndex: "rate",
|
||||
key: "rate",
|
||||
},
|
||||
{
|
||||
title: t("jobs.labels.hrs_total"),
|
||||
dataIndex: "total",
|
||||
key: "total",
|
||||
sorter: (a, b) => a.total - b.total,
|
||||
dataIndex: "expectedHours",
|
||||
key: "expectedHours",
|
||||
sorter: (a, b) => a.expectedHours - b.expectedHours,
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "total" && state.sortedInfo.order,
|
||||
render: (text, record) => record.total.toFixed(2),
|
||||
state.sortedInfo.columnKey === "expectedHours" &&
|
||||
state.sortedInfo.order,
|
||||
render: (text, record) => record.expectedHours.toFixed(5),
|
||||
},
|
||||
{
|
||||
title: t("jobs.labels.hrs_claimed"),
|
||||
dataIndex: "hrs_claimed",
|
||||
key: "hrs_claimed",
|
||||
sorter: (a, b) => a.claimed - b.claimed,
|
||||
dataIndex: "claimedHours",
|
||||
key: "claimedHours",
|
||||
sorter: (a, b) => a.claimedHours - b.claimedHours,
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "claimed" && state.sortedInfo.order,
|
||||
render: (text, record) => record.claimed && record.claimed.toFixed(2),
|
||||
},
|
||||
{
|
||||
title: t("jobs.labels.adjustments"),
|
||||
dataIndex: "adjustments",
|
||||
key: "adjustments",
|
||||
sorter: (a, b) => a.adjustments - b.adjustments,
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "adjustments" && state.sortedInfo.order,
|
||||
render: (text, record) => (
|
||||
<Space wrap>
|
||||
{record.adjustments.toFixed(2)}
|
||||
{!technician && (
|
||||
<LaborAllocationsAdjustmentEdit
|
||||
jobId={jobId}
|
||||
adjustments={adjustments}
|
||||
mod_lbr_ty={record.opcode}
|
||||
refetchQueryNames={["GET_LINE_TICKET_BY_PK"]}
|
||||
>
|
||||
<EditFilled />
|
||||
</LaborAllocationsAdjustmentEdit>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
state.sortedInfo.columnKey === "claimedHours" && state.sortedInfo.order,
|
||||
render: (text, record) =>
|
||||
record.claimedHours && record.claimedHours.toFixed(5),
|
||||
},
|
||||
{
|
||||
title: t("jobs.labels.difference"),
|
||||
@@ -112,15 +110,22 @@ export function PayrollLaborAllocationsTable({
|
||||
sorter: (a, b) => a.difference - b.difference,
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "difference" && state.sortedInfo.order,
|
||||
render: (text, record) => (
|
||||
<strong
|
||||
style={{
|
||||
color: record.difference >= 0 ? "green" : "red",
|
||||
}}
|
||||
>
|
||||
{_.round(record.difference, 1)}
|
||||
</strong>
|
||||
),
|
||||
render: (text, record) => {
|
||||
const difference = _.round(
|
||||
record.expectedHours - record.claimedHours,
|
||||
5
|
||||
);
|
||||
|
||||
return (
|
||||
<strong
|
||||
style={{
|
||||
color: difference >= 0 ? "green" : "red",
|
||||
}}
|
||||
>
|
||||
{difference}
|
||||
</strong>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
const convertedTableCols = [
|
||||
@@ -182,7 +187,7 @@ export function PayrollLaborAllocationsTable({
|
||||
render: (text, record) =>
|
||||
record.convertedtolbr_data &&
|
||||
record.convertedtolbr_data.mod_lb_hrs &&
|
||||
record.convertedtolbr_data.mod_lb_hrs.toFixed(2),
|
||||
record.convertedtolbr_data.mod_lb_hrs.toFixed(5),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -194,10 +199,10 @@ export function PayrollLaborAllocationsTable({
|
||||
totals &&
|
||||
totals.reduce(
|
||||
(acc, val) => {
|
||||
acc.hrs_total += val.total;
|
||||
acc.hrs_claimed += val.claimed;
|
||||
acc.adjustments += val.adjustments;
|
||||
acc.difference += val.difference;
|
||||
acc.hrs_total += val.expectedHours;
|
||||
acc.hrs_claimed += val.claimedHours;
|
||||
// acc.adjustments += val.adjustments;
|
||||
acc.difference += val.expectedHours - val.claimedHours;
|
||||
return acc;
|
||||
},
|
||||
{ hrs_total: 0, hrs_claimed: 0, adjustments: 0, difference: 0 }
|
||||
@@ -211,18 +216,21 @@ export function PayrollLaborAllocationsTable({
|
||||
const { data } = await axios.post("/payroll/payall", {
|
||||
jobid: jobId,
|
||||
});
|
||||
|
||||
setTotals(
|
||||
CalculateAllocationsTotals(
|
||||
bodyshop,
|
||||
joblines,
|
||||
[...timetickets, ...data],
|
||||
adjustments
|
||||
)
|
||||
);
|
||||
refetch();
|
||||
}}
|
||||
>
|
||||
Calc
|
||||
Pay All Test
|
||||
</Button>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
const { data } = await axios.post("/payroll/calculatelabor", {
|
||||
jobid: jobId,
|
||||
});
|
||||
setTotals(data);
|
||||
refetch();
|
||||
}}
|
||||
>
|
||||
Calculate Labor
|
||||
</Button>
|
||||
<Card title={t("jobs.labels.laborallocations")}>
|
||||
<Table
|
||||
@@ -241,17 +249,17 @@ export function PayrollLaborAllocationsTable({
|
||||
{t("general.labels.totals")}
|
||||
</Typography.Title>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell></Table.Summary.Cell>
|
||||
<Table.Summary.Cell></Table.Summary.Cell>
|
||||
<Table.Summary.Cell>
|
||||
{summary.hrs_total.toFixed(2)}
|
||||
{summary.hrs_total.toFixed(5)}
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell>
|
||||
{summary.hrs_claimed.toFixed(2)}
|
||||
{summary.hrs_claimed.toFixed(5)}
|
||||
</Table.Summary.Cell>
|
||||
|
||||
<Table.Summary.Cell>
|
||||
{summary.adjustments.toFixed(2)}
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell>
|
||||
{summary.difference.toFixed(2)}
|
||||
{summary.difference.toFixed(5)}
|
||||
</Table.Summary.Cell>
|
||||
</Table.Summary.Row>
|
||||
)}
|
||||
|
||||
@@ -199,7 +199,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<InputNumber min={0} max={100} />
|
||||
<InputNumber min={0} max={100} precision={2}/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("joblines.fields.lbr_types.LAA")}
|
||||
|
||||
Reference in New Issue
Block a user