Establish working version of pay all and labor calculations.

This commit is contained in:
Patrick Fic
2023-07-17 14:58:28 -07:00
parent dd085be5c7
commit c214168dcd
8 changed files with 389 additions and 334 deletions

View File

@@ -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>

View File

@@ -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>
)}

View File

@@ -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")}